我正在阅读一本关于C ++编程的书,我正在关注这些练习。一个练习要求我创建一个产生内存泄漏的程序。这个程序会产生这样的泄漏吗?
int main()
{
int * pInt = new int;
*pInt = 20;
pInt = new int;
*pInt =50;
return 0;
}
答案 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/
<强>更新强> 你的兴趣让我进行编辑
您正在为p和q分配内存:
p=new int [5];
/* ... */
q=new int;
但是你只使用无效的运算符释放p,因为应该使用delete []删除数组。你应该在某些时候使用:
释放p和qdelete[] 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”来释放空间。