C++中销毁对象数多于创建数的原因及内存泄漏疑问
为什么C++中销毁的对象数量比创建的多?
嘿,作为C++新手遇到这个问题太正常了!我来帮你拆解清楚背后的原因,以及你担心的内存泄漏问题。
核心原因:你没看到的隐式对象创建
你以为只创建了3个对象,但实际上C++在很多场景会隐式生成临时对象,这些对象你没写代码显式创建,但编译器会自动生成,执行完它们的使命后就会被销毁。常见的场景包括:
1. 值传递函数参数
当你用值传递把对象传给函数时,编译器会自动调用拷贝构造函数(或移动构造函数)创建一个参数的副本,函数执行完毕后这个副本就会被销毁。比如:
void process(MyClass obj) { /* 函数逻辑 */ } int main() { MyClass a; // 显式创建1个对象 process(a); // 隐式拷贝创建1个临时对象,函数结束后销毁它 }
这里显式创建1个,但实际创建了2个,销毁也是2个。
2. 返回值的临时对象
如果函数返回一个对象,在没有开启返回值优化(RVO)的情况下,编译器会生成一个临时对象来存储返回值,之后这个临时对象会被销毁。旧版本的MinGW可能默认没开全优化,这种临时对象就会被显式创建和销毁。比如:
MyClass createObj() { return MyClass(); // 未优化时会生成临时对象 } int main() { MyClass b = createObj(); // 隐式创建临时对象 }
3. 表达式中的临时对象
比如在表达式中直接创建对象(如MyClass() + MyClass(),假设重载了+运算符),这里会生成两个临时对象,运算后还可能生成第三个临时对象作为结果,这些都会被销毁。
关于内存泄漏:完全不用担心!
你看到销毁的对象更多,恰恰说明所有被创建的对象都被正确销毁了——包括你显式创建的,以及编译器隐式生成的临时对象。内存泄漏的定义是「创建了对象但没有销毁」,而这里的情况是你没看到所有的创建动作,不是对象没被销毁。
怎么验证?给所有构造函数加日志
要搞清楚到底有多少对象被创建,你需要把拷贝构造函数和移动构造函数也加上日志输出,而不只是默认构造函数。比如:
#include <iostream> using namespace std; class MyClass { public: MyClass() { cout << "[默认构造] 创建对象" << endl; } // 拷贝构造 MyClass(const MyClass&) { cout << "[拷贝构造] 创建对象" << endl; } // 移动构造(C++11及以上) MyClass(MyClass&&) noexcept { cout << "[移动构造] 创建对象" << endl; } ~MyClass() { cout << "[析构] 销毁对象" << endl; } };
运行这段代码后,你就能看到所有的创建动作(包括隐式的拷贝/移动),此时创建的数量和销毁的数量就会完全对应上了。
内容的提问来源于stack exchange,提问作者8JointsRoboter
相关产品推荐
相关产品推荐

