我遇到std :: list和内存泄漏问题:
class AbstractObject
{
public:
virtual void Say() = 0;
}
class RealObject : public AbstractObject
{
public:
virtual void Say() { cout << "Real Obj Says..." << endl; } //Do I need the "virtual" keyword here too?
}
class AnotherRealObject : public AbstractObject
{
public:
virtual void Say() { cout << "Another Real Obj Says..." << endl; } //Do I need the "virtual" keyword here too?
}
class PackOfObjects
{
public:
std::list<AbstractObject*> objects; //list of pointers because it doesn't let me create a list of an abstract class
void Say()
{
for(std::list<AbstractObject*>::iterator obj = objects.begin(); obj != objects.end(); obj++)
{
(*obj)->Say();
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
PackOfObjs myObjs;
RealObject objA;
myObjs.objects.push_back(&objA); //This adds 1 memory leak
AnotherRealObject objB;
myObjs.objects.push_back(&objB); //This adds another 1 memory leak
_gettch();
_CrtDumpMemoryLeaks();
return 0;
}
只是声明了PackOfObjs我已经有2个内存泄漏,如果我删除了std :: list它们会消失,并且对于我添加到列表中的每个地址它们会增加1。 我尝试清除列表和一些删除清除之前指向的所有obj的代码,但至少有2个内存泄漏仍然存在。
由于我没有使用任何 new (甚至不添加我添加的元素),我猜测列表本身会创建一些变量并且不删除它们,我该如何解决这个问题?
答案 0 :(得分:5)
_CrtDumpMemoryLeaks()
运行时,main
内分配的所有对象仍然存在。您过早地致电_CrtDumpMemoryLeaks()
。相反,试试这个:
int _tmain(int argc, _TCHAR* argv[])
{
{
PackOfObjs myObjs;
RealObject objA;
myObjs.objects.push_back(&objA); //This adds 1 memory leak
AnotherRealObject objB;
myObjs.objects.push_back(&objB); //This adds another 1 memory leak
// <- all memory used by the list is freed here
}
_gettch();
_CrtDumpMemoryLeaks();
return 0;
}
我似乎记得调用_CrtDumpMemoryLeaks
的推荐方法是在全局对象的析构函数中。对于其他全局对象来说,这可能还为时过早,但至少在main
内创建的所有对象都已经被破坏了。
struct memory_leak_dumper
{
~memory_leak_dumper(){ _CrtDumpMemoryLeaks(); }
};
memory_leak_dumper _dumper; // this is a global object
答案 1 :(得分:1)
要检查内存泄漏,您应该使用:
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
在你的主要开始
泄漏将在程序出口处检查,现在你在对象仍在堆栈时检查它们,所以你没有泄漏。
如果你使用虚方法,你应该添加虚析构函数,虽然在你的情况下它不会导致内存泄漏,但如果你的列表包含动态分配的对象,那么AbstractObject中的虚析构函数是必需的。
关于你的问题:
“//我在这里也需要”虚拟“关键字吗?”
是的,只要您的列表&lt;&gt;是基类指针类型
答案 2 :(得分:0)
要扩展K-ballo's answer,技术上_CrtDumpMemoryLeaks
检查堆上的对象。虽然你没有在堆上直接分配任何东西,但是std::list
(以及为此事件动态管理内存的所有容器)都可以 - 否则动态大小将不是一个选项。
所以不,技术上没有泄漏,但在你调用_CrtDumpMemoryLeaks
时,动态分配的内存仍在使用中,尚未被释放(尚未)。
将std::list
封装在一个单独的范围{ ... }
中,或者在建议的全局对象的析构函数中调用_CrtDumpMemoryLeaks
应该显示没有泄漏。