这会产生内存泄漏吗?

时间:2013-03-27 01:38:26

标签: c++ memory-leaks

我正在阅读一本关于C ++编程的书,我正在关注这些练习。一个练习要求我创建一个产生内存泄漏的程序。这个程序会产生这样的泄漏吗?

int main()
{
    int * pInt =  new int;
    *pInt = 20;

    pInt = new int;
    *pInt =50;

    return 0;
}

7 个答案:

答案 0 :(得分:5)

考虑到这是一个简单的例子,没有delete与您的new配对是一个泄漏。在这种情况下,为了防止泄漏,您需要以下内容:

int * pInt =  new int;
*pInt = 20;

delete pInt ;

pInt = new int;
*pInt =50;

delete pInt ;

用于检测内存泄漏的一个不错的工具是Valgrind。我在你的示例代码上运行了这个工具,如下所示:

 valgrind ./a.out

这是它产生的输出的一部分:

==14153== HEAP SUMMARY:
==14153==     in use at exit: 8 bytes in 2 blocks
==14153==   total heap usage: 2 allocs, 0 frees, 8 bytes allocated
==14153== 
==14153== LEAK SUMMARY:
==14153==    definitely lost: 8 bytes in 2 blocks

这证实了程序确实泄漏了内存。

答案 1 :(得分:3)

是。为避免泄密,每次拨打new时,您都必须与delete进行匹配。您有2次拨打new而没有拨打delete,因此您有2次泄密。

请注意,当您的程序退出时,操作系统将释放您使用new分配的所有内存。因此,内存泄漏实际上只是非平凡程序的一个问题。

答案 2 :(得分:2)

是的,这不会产生一个,而是两个内存泄漏:分配的int都被泄露了。而且,第一个是不可恢复的泄露:一旦你第二次分配pInt一个new int,第一个分配的项目就会永远消失。

答案 3 :(得分:2)

  

这个程序是否会产生泄漏?

是的,它会。

答案 4 :(得分:2)

One exercise asks me to create a program that produces a memory leak. 
     

这个程序会产生这样的泄漏吗?

     

一个完整的练习,你的代码是锻炼的更好答案!

指针和内存泄漏。这些是真正耗费开发人员大部分调试时间的项目

内存泄漏

内存泄漏可能非常烦人。以下列表描述了导致内存泄漏的一些情况。

Reassignment,  I'll use an example to explain reassignment.

char *memoryArea = malloc(10);
char *newArea = malloc(10);

这会将值分配给下面图4中所示的内存位置。

http://www.ibm.com/developerworks/aix/library/au-toughgame/fig4.gif     图4.内存位置

memoryArea和newArea已经分配了10个字节,它们各自的内容如图4所示。如果有人执行下面显示的语句(指针重新分配)

memoryArea = newArea; 

那么在本模块开发的后期阶段肯定会让你陷入艰难时期。

在上面的代码语句中,开发人员已将memoryArea指针指定给newArea指针。结果,memoryArea之前指向的内存位置变为孤立,如下面的图5所示。它无法释放,因为没有引用此位置。这将导致10个字节的内存泄漏。

http://www.ibm.com/developerworks/aix/library/au-toughgame/fig5.gif     图5.内存泄漏

Before assigning the pointers, make sure memory locations are not becoming orphaned.
Freeing the parent block first

Suppose there is a pointer memoryArea pointing to a memory location of 10 bytes. The third byte of this memory location further points to some other dynamically allocated memory location of 10 bytes, as shown in Figure 6.

http://www.ibm.com/developerworks/aix/library/au-toughgame/fig6.gif     图6.动态分配的内存

free(memoryArea)

**如果通过调用free释放memoryArea,那么newArea指针也将变为无效。无法释放newArea指向的内存位置,因为没有指针指向该位置。换句话说,newArea指向的内存位置变成孤儿并导致内存泄漏。

每当释放结构化元素(其中包含指向动态分配的内存位置的指针)时,首先遍历子内存位置(示例中为newArea)并从那里开始释放,遍历回父节点。     这里正确的实现将是:     free(memoryArea-> newArea);     自由(memoryArea);     回报值处理不当     有时,某些函数会返回对动态分配的内存的引用。调用函数负责跟踪此内存位置并正确处理它。**

char *func ( )
{
        return malloc(20); // make sure to memset this location to ‘\0’…
}

void callingFunc ( )
{
        func ( ); // Problem lies here
}

In the example above, the call to the func() function inside the callingFunc() function is not handling the return address of the memory location. As a result, the 20 byte block allocated by the func() function is lost and results in a memory leak.

夏普参考: http://www.ibm.com/developerworks/aix/library/au-toughgame/

<强>更新 你的兴趣让我进行编辑

避免C中内存泄漏的简单规则

您正在为p和q分配内存:

p=new int [5];
/* ... */
q=new int;

但是你只使用无效的运算符释放p,因为应该使用delete []删除数组。你应该在某些时候使用:

释放p和q
delete[] p;
delete q;

请注意,由于您的指针指向另一个指针的已分配缓冲区,因此您可能必须检查哪个删除操作符对应于哪个新操作。

你应该在用new []分配的缓冲区上使用delete [],并使用new分配的缓冲区删除。

  

规则1:在“malloc”之后总是写“免费”

int *p = (int*) malloc ( sizeof(int) * n );

free (p);
  

规则2:永远不要使用分配的指针。使用副本!

int *p_allocated = (int*) malloc ( sizeof(int) * n );

int *p_copy = p_allocated;

// do your stuff with p_copy, not with p_allocated!

// e.g.:

while (n--) { *p_copy++ = n; }

...

free (p_allocated);
  

规则3:不要吝啬。使用更多内存。

始终分配超出您需要的内存。完成调试后,返回并减少内存使用。如果你需要一个1000长整数的数组,分配2000,并且只有在你确定其他一切都没问题之后 - 才返回并将其减少到1000.

  

规则4:始终随身携带数组长度

无论你的阵列在哪里,都应该随身携带它的长度。一个很好的技巧是分配一个大小为n + 1的数组,并将n保存到它的0位:

int *p_allocated = (int*) malloc ( sizeof(int) * (n+1) );
int *p_copy = p_allocated+1;
p_copy[-1] = n;
// do your stuff with p_copy, not with p_allocated!
free (p_allocated);
  

规则5:保持一致。并保存评论

最重要的是要保持一致并写下你的所作所为。我总是惊讶于有多少程序员认为评论是浪费时间。他们势在必行。没有评论,你可能不记得你做了什么。想象一下,在你编写代码一年后回到你的代码,并花费无数小时试图回忆那个索引的作用。最好花几秒钟写下来。

另外,如果你保持一致,你不会经常失败。始终使用相同的机制来传递数组和指针。不要轻易改变你做事的方式。如果您决定使用我之前的技巧,请在任何地方使用它,否则您可能会发现自己回到了一个不存在的地方,因为您忘记了您选择的引用类型。

参考:http://mousomer.wordpress.com/2010/11/03/simple-rules-to-avoid-memory-leaks-in-c/

答案 5 :(得分:1)

是和否。当使用新的int指针覆盖pInt时,会丢失先前分配的内存,但是当程序返回时,大多数现代操作系统将清理此内存,以及最后不释放pInt而导致的内存丢失。 / p>

所以从本质上讲,是的,这样的事情会导致两次内存泄漏。

答案 6 :(得分:1)

确实如此,因为您使用语句“new int”分配空间,但不要使用“delete”来释放空间。