即使指针未初始化,"if(pointer) delete ponter"也会尝试删除
"if(pointer) delete ponter" trys to delete even when pointer is not initialized
我写了一个非常小的 observable 实现。当一个观察者被注册时,它会删除旧的观察者并创建新的观察者。然而,它试图删除指针,即使它没有被初始化。代码如下:
Observable.h
class Observable
{
public:
Observable();
virtual void registerObserver(Observer * O);
virtual ~Observable();
protected:
Observer * myObserver;
};
Observable.cpp
#include "Observable.h"
Observable::Observable()
{
}
Observable::~Observable()
{
if(myObserver)
delete myObserver;
}
void Observable::registerObserver(Observer * O)
{
if(myObserver)
delete myObserver;
myObserver=O;
}
GUI * gui = new GUI(); // GUI extends Observer
Model * m = new Model(); //Model extends Observable
m->registerObserver(gui); //I get a segfault inside this call
如果我遍历registerObserver
,我看到即使我从未初始化myObserver
,语句 If (myObserver)的计算结果为true。这将导致未初始化的指针被删除和segfault。
值得注意的是,如果我运行发布版本,我不会得到段错误。我只在调试版本中得到错误。
我的印象是if(myObserver)只有在指针完整的情况下才会求值为true。(即初始化未删除)
其他人已经解释了为什么由于未初始化的指针而导致分割错误,以及如何解决这个问题。你仍然有其他错误等待发生,因为你没有遵循三原则。如果你复制了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() );
}
您没有在代码中初始化myObserver
,因此它的初始值是不可知的。您需要显式地初始化它:
Observable::Observable() : myObserver(nullptr)
{
}
没错。你从来没有初始化它,所以它的值是undefined。这意味着您不知道它可能包含什么值,因为没有设置任何值。它当然不能保证为NULL。
应该始终初始化指针。通常的方法是在构造函数中使用初始化列表语法:
Observable::Observable()
: myObserver(NULL)
{ }
c++成员变量默认不初始化。这意味着您的myObserver
变量在您的示例中不能依赖于0
。
你需要在你的构造函数中添加一个初始化,以摆脱未定义行为。
你需要
Observable::Observable() : myObserver(0)
{
}
!mypointer
只有在mypointer
等于0 (NULL
, nullptr
等)时才会计算为true,但在显式设置此值之前,它只是未定义—一些随机值。
- 运算符C++ "delete []"仅删除 2 个前值
- g++用户定义的动态链接库上的全局new和delete运算符
- 为什么"delete"关键字不删除节点?
- "delete"在 C++ 中实际上做了什么?
- 析构函数和'delete'之间的区别
- 如何知道何时调用删除以及何时调用 delete[] C++?
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 体系结构x86_64的未定义符号:std:terminate(),typeinfo,运算符delete[],运算符new
- 析构函数中的"delete this"
- 为什么数组大小信息可用于"sizeof"运算符和 delete[] 运算符,但在将数组作为参数传递到
- 即使在使用 delete[] 后仍保留的元素
- 如果我在下面的代码片段中添加"delete[] d;",为什么我得到零?
- C++原始指针和"delete"
- 为什么 std::vector 使用 std::分配器而不是运算符 new 和 delete?
- 重载 new 和 delete 会导致 valgrind 错误
- 为什么"delete"操作员给我访问权限冲突
- 析构函数是否会自动调用 delete[] C++?
- C++"::delete"的目的是什么?
- 使用 delete [] 运算符取消分配类中数据成员的内存
- 即使指针未初始化,"if(pointer) delete ponter"也会尝试删除