1

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

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

    pInt = new int;
    *pInt =50;

    return 0;
}
4

7 回答 7

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

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

于 2013-03-27T01:40:21.020 回答
3

是的。为避免泄漏,每次调用new时,都必须对delete. 您有 2 次呼叫new,没有呼叫delete,因此您有 2 次泄漏。

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

于 2013-03-27T01:40:51.160 回答
2

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

于 2013-03-27T01:39:58.477 回答
2

这个程序会产生吸漏吗?

是的,它会的。

于 2013-03-27T01:40:00.783 回答
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); 空闲(内存区域);返回值处理不当有时,某些函数会将引用返回到动态分配的内存。跟踪此内存位置并正确处理它成为调用函数的责任。**

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”之后写“free”</p>

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/

于 2013-03-27T01:53:46.310 回答
1

是和不是。当 pInt 被一个新的 int 指针覆盖时,你会丢失之前分配的内存,但是当程序返回时,大多数现代操作系统会清理这个内存,以及由于没有在最后释放 pInt 而丢失的内存。

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

于 2013-03-27T01:40:56.003 回答
1

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

于 2013-03-27T01:41:26.040 回答