C++析构函数不负责删除对象本身?那对象内存由谁释放?
C++ 析构函数与对象生命周期问题解答
首先先澄清认知偏差:对象生命周期结束时,析构函数执行和对象本身内存释放是两个绑定执行的步骤:系统先调用析构函数清理对象内部申请的外部资源,再回收对象本身占用的内存,二者并不矛盾。
针对你提出的三个问题,答案如下:
- 不会残留1万个StrPtr对象,没有任何内存泄漏或对象残留
- 不需要等到for循环结束才删除对象,每个对象的销毁时机远早于for循环结束
- 你认为「每次someF()执行完毕后,内部创建的StrPtr对象会因超出作用域被删除」的认知完全正确
具体执行逻辑说明
你给出的代码中,StrPtr s是定义在someF函数内部的栈对象,栈对象的生命周期严格和所属作用域绑定,完整执行逻辑可参考注释:
class StrPtr { private: string * str; public: StrPtr() : str(new string()) {} ~StrPtr() { delete str; } void add(char c) { str->push_back(c); } }; void someF() { StrPtr s; // 栈上开辟StrPtr内存,执行构造函数,给str分配堆上的string对象 s.add('a'); } // 函数执行结束,作用域销毁:先调用s的析构函数释放str指向的堆内存,再回收s本身占用的栈内存 int main() { for (int i = 0; i < 10000; i++) { someF(); // 每次调用结束,对应的StrPtr对象已经被完全清理 } return 0; }
也就是说每一次someF调用返回时,对应的StrPtr对象就已经完成了析构+内存回收,循环调用1万次也不会有对象累积,完全不需要等到for循环结束才处理。
补充说明:只有用
new创建的堆对象,才需要手动调用delete来触发析构、回收对象本身的内存,栈对象的生命周期完全由编译器自动管理,不需要手动干预。
内容的提问来源于stack exchange,提问作者Shiny_and_Chrome
相关产品推荐
相关产品推荐

