了解 C/C++ 中的内存泄漏 [关闭]
-
29-09-2020 - |
题
我在这里看一个例子:https://blog.parasoft.com/finding-memory-leaks-in-c
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *string, *string_so_far;
int i, length; length = 0;
for(i=0; i<argc; i++) {
length += strlen(argv[i])+1;
string = malloc(length+1);
/* * Copy the string built so far. */
if(string_so_far != (char *)0)
strcpy(string, string_so_far);
else *string = '\0';
strcat(string, argv[i]);
if(i < argc-1) strcat(string, " ");
string_so_far = string;
}
printf("You entered: %s\n", string_so_far);
return (0);
}
当我们使用以下参数执行程序时,请阅读:
hello this is a test
变量 string_so_far 指向作为先前循环迭代的结果分配的字符串“hello”。但我不明白怎么办?一步一步的解释会非常有帮助。
其次,我在课程材料中看到了这个例子:
int countPrimes(int n)
{
PrimeSet *p = new PrimeSet(n);
return( p->countPrimeNumbers() );
}
有人说这里存在内存泄漏,但我不太明白这是怎么回事,可能是因为我不确定这里到底发生了什么。
解决方案
在第一个示例中,您使用 malloc
在变量的循环内。这 malloc
调用保留一个内存块并返回该块的首地址。您需要删除才能阻止 free
如果您不再需要它。如果程序员希望扩展内存块,更好的选择是 realloc
. 。阅读更多关于 realloc
在 http://www.cplusplus.com/reference/cstdlib/realloc/.
在第二个示例中,指针所在的对象 p
指向在堆上初始化并将保留在堆中直到程序员使用 delete
. 。在堆上创建对象的更安全的替代方法是在堆栈上创建对象,这将在方法调用完成后删除所有数据。
int countPrimes(int n){
PrimeSet p(n);
return( p.countPrimeNumbers() );
}
如果内存管理没有像第二个示例中那样正确完成,则在丢失对该对象的唯一引用后将无法删除该对象,因此会发生内存泄漏。
其他提示
在第二个示例中,您为 PrimeSet 对象分配空间并初始化它,然后调用 countPrimeNumbers 函数。PrimeSet 对象仍然存在,它仍然占用内存,它可能分配了更多内存,并且所有内存仍然被占用但无法访问。这是内存泄漏:内存已被占用但无法使用。
不隶属于 cs.stackexchange