为什么这里没有内存泄漏
Why is there no memory leak here
我试图回答这个问题,所以我决定创建以下简单的测试用例,以便OP可以自己看到内存泄漏。
#include<iostream>
class MyObject
{
public:
MyObject(){std::cout << "creation of my object" << std::endl;}
virtual ~MyObject(){std::cout << "destruction of my object" << std::endl;}
};
void processMyObject(MyObject foo)
{
}
int main()
{
processMyObject(*new MyObject());
return 0;
}
我编译了它:
g++ test.cpp -o test
然后,我看到一个意想不到的输出:
creation of my object
destruction of my object
我完全不知道这里发生了什么。谁能给我解释一下?
PS:我使用了g++ 4.6.3
由于按值将对象传递给函数,因此会引发复制或移动复制构造。但是您没有使用原始内存泄漏检查器来跟踪它。你可以提供你自己的复制构造函数,然后你会看到两个对象被创建,只有一个对象被销毁:
#include<iostream>
class MyObject
{
public:
MyObject() {std::cout << "creation of my object" << std::endl;}
MyObject(const MyObject&) {std::cout << "copy creation of my object" << std::endl;}
~MyObject() {std::cout << "destruction of my object" << std::endl;}
};
void processMyObject(MyObject foo) {}
int main()
{
processMyObject(*new MyObject());
}
输出:creation of my object
copy creation of my object
destruction of my object
因为你取的是MyObject
的值
因此有一个销毁。但它是在processMyObject
的末尾销毁foo
参数。
在这种情况下,*new
实际上仍然泄漏。
EDIT:正如juanchopanza指出的,您还需要在复制构造函数和移动构造函数中打印语句。
你的代码中发生了什么
- 您构建一个对象并获取有关它的信息(
creation of my object
) - 传递给函数复制构造函数,但不报告任何内容
- 副本被销毁-您获得有关它的信息(
destruction of my object
) - 原始实例泄漏,尽管事实上,你没有任何关于它的信息。
怎么看?
在建造和破坏过程中简单地报告指针给this
(快速而肮脏,请不要抱怨):
class MyObject
{
public:
MyObject(){std::cout << "creation of my object (" << (int)this << ")" << std::endl;}
virtual ~MyObject(){std::cout << "destruction of my object (" << (int)this << ")" << std::endl;}
};
结果:creation of my object (165437448)
destruction of my object (-1076708692)
如你所见,销毁的对象不同于创建的对象。
如何"修复"它来显示泄漏?
最简单的方法来"修复"你的代码是通过指针传递对象:
#include<iostream>
class MyObject
{
public:
MyObject(){std::cout << "creation of my object" << std::endl;}
virtual ~MyObject(){std::cout << "destruction of my object" << std::endl;}
};
void processMyObject(MyObject * foo)
{
}
int main()
{
processMyObject(new MyObject());
return 0;
}
另一个选项是报告复制因子和移动因子:
class MyObject
{
public:
MyObject(){std::cout << "creation of my object" << std::endl;}
MyObject(const MyObject & obj) { std::cout << "copy-ctor" << std::endl; }
MyObject(MyObject && obj) { std::cout << "move-ctor" << std::endl; }
virtual ~MyObject(){std::cout << "destruction of my object" << std::endl;}
};
实际上存在内存泄漏。仅仅因为您的对象被销毁,并不意味着您删除了通过new
获得的资源。您必须显式地使用delete
。
编辑
下面是结果:
- 您正在动态调用默认构造函数,并将其传递给函数调用。打印第一条消息。
- 作为函数调用的一部分,对象被传递给
processMyObject()
,使用复制构造函数在该范围内创建一个新对象,该构造函数已由编译器隐式定义。 - 当该对象(在
processMyObject()
中)超出作用域时,调用它的析构函数,打印第二条消息。
因此,打印第一条消息的实例与打印第二条消息的实例是不同的。
希望能把事情说清楚。
相关文章:
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- 瓦尔格林德的内存泄漏使用新的
- 无法找出我的代码中的内存泄漏
- C++ 结构内部的unordered_map会导致内存泄漏问题吗?
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- Shared_ptr双链接列表内存泄漏
- C++ 在类中使用常量引用文本时 O2 内存泄漏