"if(pointer)delete ponter"即使没有初始化指针也会删除

Dan*_*cci 2 c++ qt pointers segmentation-fault

我写了一个非常小的Observeable实现.当观察者注册时,它会删除旧观察者并启动新观察者.但是,即使它尚未初始化,它也会尝试删除指针.代码如下:

Observable.h

class Observable
{
public:
    Observable();
    virtual void registerObserver(Observer * O);
    virtual ~Observable();

protected:
    Observer * myObserver;
};
Run Code Online (Sandbox Code Playgroud)

Observable.cpp

#include "Observable.h"

Observable::Observable()
{
}


Observable::~Observable()
{
    if(myObserver)
        delete myObserver;
}

void Observable::registerObserver(Observer * O)
{
    if(myObserver)
        delete myObserver;
    myObserver=O;
}
Run Code Online (Sandbox Code Playgroud)

所有主要做的是

GUI * gui = new GUI();      // GUI extends Observer
Model * m = new Model();    //Model extends Observable
m->registerObserver(gui);   //I get a segfault inside this call
Run Code Online (Sandbox Code Playgroud)

如果我单步执行registerObserver,我会看到即使我从未初始化myObserver,语句if(myObserver)的计算结果为true.这导致未初始化的指针被删除并且出现seg错误.

值得注意的是,如果我运行发布版本,我就不会遇到段错误.我只在调试版本中得到错误.

我的印象是if(myObserver)只有在指针完好无损的情况下才会评估为true.(即初始化但未删除).

Pra*_*ian 6

其他人已经解释了为什么你因为未初始化的指针而得到分段错误,以及如何解决这个问题.你还有其他的bug等待发生,因为你没有遵循三条规则.如果您复制Observable该类,则两个实例现在都将包含副本myObserver,并且两者都将尝试delete在其各自的析构函数中指针,从而导致未定义的行为,并可能导致崩溃.

更好的实现是遵循零规则而不是自己管理指针.

#include <memory>

class Observable
{
public:
    Observable();
    virtual void registerObserver( std::unique_ptr<Observer> O );
    virtual ~Observable();

protected:
    std::unique_ptr<Observer> myObserver;
};

Observable::Observable()
// no need to initialize pointer
{}

Observable::~Observable()
{
  // no need to delete pointer manually
}

void Observable::registerObserver( std::unique_ptr<Observer> O )
{
    myObserver.reset( O.release() );
}
Run Code Online (Sandbox Code Playgroud)