我在这里看一个例子: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. 。阅读更多关于 reallochttp://www.cplusplus.com/reference/cstdlib/realloc/.

在第二个示例中,指针所在的对象 p 指向在堆上初始化并将保留在堆中直到程序员使用 delete. 。在堆上创建对象的更安全的替代方法是在堆栈上创建对象,这将在方法调用完成后删除所有数据。

int countPrimes(int n){
   PrimeSet p(n);
   return( p.countPrimeNumbers() );
}

如果内存管理没有像第二个示例中那样正确完成,则在丢失对该对象的唯一引用后将无法删除该对象,因此会发生内存泄漏。

其他提示

在第二个示例中,您为 PrimeSet 对象分配空间并初始化它,然后调用 countPrimeNumbers 函数。PrimeSet 对象仍然存在,它仍然占用内存,它可能分配了更多内存,并且所有内存仍然被占用但无法访问。这是内存泄漏:内存已被占用但无法使用。

许可以下: CC-BY-SA归因
不隶属于 cs.stackexchange
scroll top