我最近正在编写一个分层状态机。我想在转移到另一个超级州时设置一个初始子状态。
因此,我有如下代码来设置初始状态。第一个版本
void Foo::setInitialSubState(State* next_state){
if(state_)
delete state_;
state_ = next_state;
state_->enter(*this);
}
然后我发现if(state_)总是返回true ..所以我删除了它。在构造函数Foo :: Foo()中调用此函数。
Foo::Foo()
{
setInitialSubState(new State());
}
当我想删除state_时,存在段错误错误。所以我在构造函数中初始化成员var state_。
Foo::Foo()
{
state_ = 0;
setInitialSubState(new State());
}
这将解决段故障问题。
当我使用setInitialSubState(new State())时,我想知道是否存在内存泄漏问题?我无法弄清楚..我怎样才能改变if(state_)以避免delete()导致段错误?
感谢您的所有建议..
---- ----编辑
为了让自己更清楚一下内存泄漏部分,我想我可以将这个问题重新解释为
void Foo::setInitialSubState(State* next_state)
{
state_ = next_state;
delete state_;
}
Foo::Foo()
{
state_ = 0;
setInitialSubState(new State());
}
有内存泄漏吗?
答案 0 :(得分:3)
最初state_
的未初始化指针有一些值,这就是if(state_)
输入并尝试delete
某个随机指针的原因。
在零指针上调用delete是安全的,这就是你的修复工作的原因。
关于内存泄漏:如果Foo类没有析构函数,那么你可以拥有一个,但是要确保你应该发布更多的代码..
答案 1 :(得分:1)
以下函数没有执行任何操作,您正在删除传递给该函数的对象。如果state_先前指向某个东西,那么它将导致内存泄漏。
void Foo::setInitialSubState(State* next_state)
{
state_ = next_state; // state_ points to the object that next_state points to.
delete state_; // deletes what state_ and next_state points to.
}
另一种方法是将state_声明为智能指针,然后您不需要删除指针
std::unique_ptr<State> state_;
...
void Foo::setInitialSubState(State* next_state)
{
state_ = std::make_unique<State>(next_state);
}
下面的代码很好,尽管您可能希望使用nullptr
而不是0来更清楚state_
是一个指针并将其移动到初始化列表:
Foo::Foo() : state_(nullptr)
{
setInitialSubState(new State());
}
答案 2 :(得分:0)
如果您使用的是g ++,那么valgrind is your friend。 OSX,iOS,Windows,Android,Solaris等类似的工具......
一些商业,一些免费。四处询问。
这些在任何C / C ++程序员工具箱中都是必不可少的,它会向您显示存在问题及其位置。