Æle*_*lex 3 c++ memory-management heap-memory
我有这个小片段:
Action* newAction(Agent& a, ACTION_MODE& m)
{
Action *new_action;
do
{
new_action = new Action(a,m);
}
while (!state->addAction(new_action));
return new_action;
}
Run Code Online (Sandbox Code Playgroud)
state->addAction(Action *a); 如果添加*a,则返回true;如果*a未添加,则返回false(检查*a是否已存在).
现在,我知道很多人认为goto被认为是邪恶的,所以,在上面的代码片段中,在每个循环中重新分配new_action而不删除它,是不是错了?
以下片段不会更"明智"吗?
retry :
Action *new_action = new Action(a,m);
if (state->addAction(new_action))
{
return new_action;
}
else
{
delete new_action;
goto retry;
}
Run Code Online (Sandbox Code Playgroud)
如果这看起来很简单,我很抱歉,这是我一段时间以来一直想知道的事情.什么是正确的,删除内存然后重新分配,或者我可以立即重新分配?
编辑:
会更好吗?
Action* newAction(Agent& a, ACTION_MODE& m)
{
// state will only allow an action to be added if it does not already exist
Action *new_action = new Action(a,m);
if (!new_action) return 0;
while (!state->addAction(new_action))
{
delete new_action;
new_action = new Action(a,m);
}
return new_action;
}
Run Code Online (Sandbox Code Playgroud)
此函数的调用者需要一个已添加到状态的新操作,因此必须在此处进行删除.
您在该代码中可能存在内存泄漏,因为每次循环都会创建一个新操作,但如果无法添加,则不会释放它.更好的方法是将动作创建移到循环之外,例如:
Action *newAction (Agent& a, ACTION_MODE& m) {
Action *new_action = new Action(a,m);
while (!state->addAction(new_action))
;
return new_action;
}
Run Code Online (Sandbox Code Playgroud)
这比连续删除和重新创建操作更有效,应优先使用.
我还修复了返回类型,以便编译器不会抱怨,如果你永远无法添加动作,你应该引入某种失败策略.
就像是:
Action *newAction (Agent& a, ACTION_MODE& m) {
// Try to make action, return null if no go.
Action *new_action = new Action(a,m);
if (new_action == 0)
return 0;
// Try a limited number of times to add action to state.
int limit = 10;
while (!state->addAction(new_action)) {
if (--limit == 0)
break;
// Optional sleep if desired.
}
// If that didn't work, delete action and return null.
if (limit == 0) {
delete new_action;
return 0;
}
// Otherwise the action was added, return it.
return new_action;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1255 次 |
| 最近记录: |