为什么调用基类析构函数会使此程序崩溃
Why does calling the Base class destructor crash this program?
class ParentClass {
protected:
int* intArray;
public:
~ParentClass(){
delete [] intArray;
}
};
class ChildClass : public ParentClass {
public:
ChildClass() : ParentClass() {
intArray = new int[5];
}
};
int main(int argc, const char * argv[]) {
ChildClass child;
child.~ChildClass(); //This line crashes the program. why??
}
它引发的特定错误:初始化(37640,0x7fff78623300( malloc: * 对象 0x100100aa0 的错误:未分配正在释放的指针* 在malloc_error_break中设置断点进行调试
指针引用intArray
在 ParentClass
中声明,错误指出内存未分配,但它是在ChildClass
构造函数中分配的。
有人可以解释一下生成此错误的过程是什么?
问题不在于intArray
没有分配,而在于你解除了两次分配。
ChildClass child;
实例化ChildClass
实例并调用默认构造函数,该构造函数分配intArray
很好,没有问题。
然后,您的代码显式调用析构函数(对于堆栈分配/自动对象,您通常不需要这样做(。
然后,编译器在范围清理期间插入对析构函数的另一个调用,这会导致第二次调用delete[]
,这是不正确的,并导致崩溃。调试器可能会报告函数的最后一行(显式析构函数调用所在的位置(,而它确实应该指向右大括号。
可以肯定的是,在析构函数中设置断点并运行程序,看看命中了多少次。
您遇到未定义的行为。 从C++标准:
为对象调用析构函数后,该对象将不再存在;如果 为生存期已结束的对象调用析构函数 (3.8(。[示例:如果析构函数为自动 对象被显式调用,块随后以通常 调用对象的隐式销毁,行为未定义。
child
是main()
的本地对象。 当离开函数范围时,它会自动销毁。
不幸的是,您在离开函数之前通过显式调用 detructor 手动销毁它。 所以它被摧毁了两次(一次太多(:第二次崩溃了!
您不必销毁本地对象。仅当使用 new
分配动态对象时,指针才需要显式销毁。 但是,您应该使用delete
删除它们。
析构函数的显式调用仅在极少数情况下相关:当您想要重用具有 placement-new 的动态对象的存储时。
备注:
在ParentClass
中,您应该将intArray
初始化为 nullptr。 这将确保如果意外地没有进行分配,delete
不会尝试释放单元化指针。
- 程序崩溃并显示"std::out_of_range"错误
- 试图创建流或fopen时程序崩溃
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- 如何找出应用程序崩溃的原因 - Win 10 LTSB
- 操纵安卓相机的深度图导致应用程序崩溃
- 为什么当我尝试搜索双链表中第一个数据条目之外的数据时,程序崩溃了?
- DLL Made with CMake 使程序崩溃
- 程序崩溃使用boost::asio
- 调用 free() 有时会导致程序崩溃
- 邮件加密程序崩溃
- 调用 java 的回调() 时应用程序崩溃.由于 detatchThread 而获得运行时错误
- 比较迭代器会使程序崩溃,而不会在自定义气泡排序实现中出现错误
- For 循环在尝试读取数组 c++ 时程序崩溃
- 即使有 0 个错误,Getter 似乎也会使程序崩溃
- Windows桌面程序保存您的计算机会话 - 基于程序崩溃时的恢复会话
- 无法访问的代码如何导致我的程序崩溃?
- 矢量迭代器在尝试调用函数时使我的程序崩溃
- QCompleter set模型使应用程序崩溃
- 使用唯一指针调用函数会使我的程序崩溃
- 删除SDL_PollEvent时程序崩溃