目前,我一直在反对学校作业,正在处理一些非常讨厌的内存泄漏。在调试时,我将部分问题缩小为一段代码。
这是我调整的代码的极简化版本,用于说明泄漏:
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
do {
char *name = new char;
char *cname = new char[10];
cin >> cname;
name = cname;
delete [] name;
} while(false);
_CrtDumpMemoryLeaks();
所以我的问题是,为什么会产生内存泄漏?我尝试了很多东西来修复它,但没有任何作用。
编辑:
啊,似乎我误解了指针是如何运作的。出于某种原因,我假设没有值的指针初始化指向 NULL 而不是内存块,因此不需要处理。简单的问题得到简单的答案。谢谢。
答案 0 :(得分:2)
你召唤新的两次,但只删除一次。
答案 1 :(得分:1)
你做char* name = new char;
但稍后您用name
name = cname;
的值
以便永远不会删除原始new char
。
答案 2 :(得分:0)
显然,您还没有尝试删除name
- 您在重置char
之前分配的第一个name
并丢失对初始块的所有引用...
答案 3 :(得分:0)
只需按照代码查看已分配和释放的内容:
char *name = new char; // Block 1, name references it
char *cname = new char[10]; // Block 2, cname references it
:
name = cname; // name/cname now reference block 2 ***
delete [] name; // free up block 2
您可以在***
行看到丢失指向块1的指针,因此存在内存泄漏。即使你有代码试图释放第1块,你也不再在那之后引用它。
如果你将失去对内存块的所有访问权限,你最好先释放它:
char *name = new char; // Block 1, name references it
char *cname = new char[10]; // Block 2, cname references it
:
delete name; // free up block 1
name = cname; // name/cname now reference block 2 ***
delete [] name; // free up block 2
至于你的评论:
出于某种原因,我假设没有值的初始化指针指向NULL而不是内存块,因此不需要处理。
如果未指定,则指针初始化为什么,这取决于几个因素。但是,这与此无关,因为你做初始化它。如果您希望将指针设置为NULL,请执行以下操作:
char *name = 0; // not "new char".