我正在关注一本关于 C++ 编程的书,并且正在关注练习。一个练习要求我创建一个产生内存泄漏的程序。这个程序会产生这样的泄漏吗?
int main()
{
int * pInt = new int;
*pInt = 20;
pInt = new int;
*pInt =50;
return 0;
}
我正在关注一本关于 C++ 编程的书,并且正在关注练习。一个练习要求我创建一个产生内存泄漏的程序。这个程序会产生这样的泄漏吗?
int main()
{
int * pInt = new int;
*pInt = 20;
pInt = new int;
*pInt =50;
return 0;
}
考虑到这是一个微不足道的例子,没有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
这证实了该程序确实泄漏了内存。
是的。为避免泄漏,每次调用new
时,都必须对delete
. 您有 2 次呼叫new
,没有呼叫delete
,因此您有 2 次泄漏。
请注意,当您的程序退出时,操作系统将释放您分配的所有内存new
。所以内存泄漏实际上只是非平凡程序的问题。
是的,这产生的不是一个,而是两个内存泄漏:两个分配int
的 s 都被泄漏。此外,第一个被不可恢复地泄露:一旦你分配pInt
了new int
第二次,第一个分配的项目就永远消失了。
这个程序会产生吸漏吗?
是的,它会的。
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/
更新: 您的兴趣让我进行编辑
您正在为 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/
是和不是。当 pInt 被一个新的 int 指针覆盖时,你会丢失之前分配的内存,但是当程序返回时,大多数现代操作系统会清理这个内存,以及由于没有在最后释放 pInt 而丢失的内存。
所以本质上,是的,这样的事情会导致两次内存泄漏。
确实如此,因为您使用“new int”语句分配空间,但不要使用“delete”来释放空间。