C++静态与动态对象析构顺序及delete后sizeof问题咨询
C++静态与动态对象的析构函数调用及sizeof问题解析
已知知识点:静态分配的对象会自动调用析构函数,动态分配的对象需手动调用析构函数。
疑问与问题
- 疑问1:当同时创建一个静态对象和一个动态对象时,它们的析构函数会在对象超出作用域时同时被调用吗?
- 具体问题1:为何动态对象的析构函数先被调用?
- 具体问题2:为何调用delete销毁动态对象后,其sizeof结果仍非零?
代码示例
#include <bits/stdc++.h> using namespace std; // Destructor (NO return type & NO input parameter) class Hero { public: int health; Hero() { // constructor cout << "constructor is called" << endl; } ~Hero() {// destructor cout << "destructor is called" << endl; } }; int main(){ Hero h1; // static allocation (automatically call destructor) Hero *h2 = new Hero; // dynamic allocation (manually call destructor) delete h2; cout << "Size (static) : " << sizeof(h1) << endl; cout << "Size (dynamic) : " << sizeof(h2) << endl; return 0; }
输出显示动态对象析构函数先执行,且动态对象指针的sizeof值非零。
问题解答
1. 动态对象的析构函数为何先被调用?
你的代码里,动态对象h2是通过new在堆上分配的,随后你主动调用了delete h2——这个操作会立刻触发动态对象的析构函数,释放它占用的堆内存。而静态对象h1是分配在栈上的,它的析构函数要等到**当前作用域结束时(也就是main函数执行完return 0之后)**才会自动调用。
代码的实际执行顺序是:
- 创建静态对象
h1,调用构造函数 - 创建动态对象
h2,调用构造函数 - 执行
delete h2,立即调用动态对象的析构函数 - 输出两个
sizeof结果 main函数结束,静态对象h1超出作用域,调用其析构函数
这就是你看到动态对象析构函数先执行的原因。
2. 调用delete销毁动态对象后,其sizeof结果仍非零?
这里你搞混了动态对象本身和指向动态对象的指针的区别:
h2是一个指针变量,它存的是动态对象在堆内存中的地址,不是对象本身。sizeof(h2)计算的是指针变量的大小,和指针指向的对象有没有被销毁完全没关系。在32位系统里指针大小通常是4字节,64位系统是8字节——哪怕你调用delete释放了对象,指针变量本身依然存在(只是变成了野指针,指向的内存已无效),它的大小始终是当前系统下指针的固定长度。
而sizeof(h1)计算的是静态对象h1的实际大小,因为h1是Hero类的实例,包含一个int成员,所以大小等于sizeof(int)(通常4字节)。
3. 静态与动态对象的析构函数是否会在对象超出作用域时同时被调用?
不会。静态分配的栈对象,析构函数会在作用域结束时自动调用;而动态分配的堆对象,析构函数只有在手动调用delete(或者用智能指针这类自动管理工具)时才会触发,和作用域结束没有直接关联。如果不手动调用delete,动态对象的析构函数永远不会被执行,会造成内存泄漏。
内容的提问来源于stack exchange,提问作者balajirai
相关产品推荐
相关产品推荐

