2015-10-08 170 views
-2

目前我一直对学校作业感兴趣,正在处理一些非常讨厌的内存泄漏问题。在调试时,我将问题的一部分缩减为一段代码。为什么此代码会产生内存泄漏?

这里是代码,我调整来说明泄漏的极度简化版本:

_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

'的char * name = nullptr'将指向没有记忆,但调用'new'分配内存(并因此需要被释放) – Tas

+0

您分配一个字符,分配10个字符,做一些东西,删除10个字符,但不要删除单个字符(你实际上并不需要分配,但你做了)。 – immibis

回答

2

您呼叫新的两次,但只删除一次。

+0

但更糟糕的是,他覆盖了他的一个分配,之后永远不能删除,而第一个分配甚至不需要。 – Les

0

显然你还没有尝试删除name - 第一char您重置name到别的东西,失去所有引用到初始块之前分配...

+0

Downvoter请解释一下吗? – John3136

+0

+0.9抵消downvote原因这篇文章没有错 – Tas

+1

@Tas,是一个阴暗的尝试绕过“+一个”的评论禁止?如果是这样,它可能应该是'+0.999 ...'。或者“+ one”作为另一种选择,显然:-) – paxdiablo

1

你做char* name = new char;

,但后来你用name = cname;

代替(忘记)name的值,以便原始new char从不被删除。

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". 
相关问题