为什么这段代码会产生内存泄漏?

时间:2015-10-08 00:31:48

标签: c++

目前,我一直在反对学校作业,正在处理一些非常讨厌的内存泄漏。在调试时,我将部分问题缩小为一段代码。

这是我调整的代码的极简化版本,用于说明泄漏:

   _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 而不是内存块,因此不需要处理。

简单的问题得到简单的答案。谢谢。

4 个答案:

答案 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".