我前段时间读到向量导致内存泄漏取决于它们的使用方式,但我想问一下:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main()
{
vector<somePtr*> listPtrs;
return 0;
//Detects memory leaks
}
这并没有发现任何东西:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main()
{
{
vector<somePtr*> listPtrs;
}
return 0;
//No memory leaks detected
}
在清除指针之前,正在从向量中删除对象。 我想我记得读过它们所在的块之后会自动删除向量和列表以及其他std容器,所以在示例1中我得到了内存泄漏,因为在块结束之前调用了内存泄漏函数,所以向量还活着并造成它。
我不确定它,但是我已经有一段时间了,因为我认为我读过这篇文章,而且我只能找到关于没有被删除的对象的问题,只是删除指针。
这是真的吗?如果我使用包含向量和列表的全局类,我会得到内存泄漏吗?
答案 0 :(得分:10)
您调用_CrtDumpMemoryLeaks
的重要性非常重要,因为所有已用内存可能尚未发布。例如,在下面的示例中,如果在_CrtDumpMemoryLeaks()
超出范围之前调用listPtrs
,则已分配的任何内存都将包含在泄漏内存列表中。
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>
int main()
{
std::vector<struct Foo*> listPtrs;
_CrtDumpMemoryLeaks();
return 0;
}
在下面的示例中,listPtrs
在调用_CrtDumpMemoryLeaks
之前超出了范围,因此它已分配的任何内存都将被释放,而不会列在泄漏内存块中。
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>
int main()
{
{
std::vector<struct Foo*> listPtrs;
}
_CrtDumpMemoryLeaks();
return 0;
}
同样,如果在 main返回后调用_CrtDumpMemoryLeaks
,则应释放由std::vector
分配的任何资源。同样,这是因为listPtrs
现已超出范围,并且已调用std::vector
的析构函数。
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>
// Call _CrtDumpMemoryLeaks after main has returned and before program terminates.
struct AtExit
{
~AtExit() { _CrtDumpMemoryLeaks(); }
} doAtExit;
int main()
{
std::vector<struct Foo*> listPtrs;
return 0;
}
我强烈建议使用智能指针而不是裸指针。它让它们在冬天保持温暖,你不必担心使用delete
。
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>
#include <memory>
// Call _CrtDumpMemoryLeaks after main has returned and before program terminates.
struct AtExit
{
~AtExit() { _CrtDumpMemoryLeaks(); }
} doAtExit;
int main()
{
std::vector<std::unique_ptr<struct Foo*>> listPtrs;
return 0;
}
答案 1 :(得分:1)
在两段代码中,您已在堆栈上分配了vector<>
。因此,当向量的超出范围时,将调用向量的析构函数。我不知道你正在使用什么样的检漏仪,但是如果它在主要出口之前检查是否有泄漏,它确实可以检测到泄漏,但它实际上并不是泄漏。
当你遇到内存泄漏问题时,std::vector
析构函数不会对向量中的项调用delete
,尽管它会调用它们的析构函数。因此vector<int>
和vector<MyClass>
很好,因为向量包含实际对象并将其称为析构函数。另一方面,如果你有vector<MyClass*>
,你需要小心;删除该向量将不释放与其指向的MyClass
对象关联的内存。