“ptr = malloc(sizeof(char)* 10)”使用多次,一个接一个地分配指向同一个内存块的指针还是导致内存泄漏?

时间:2013-05-13 14:51:29

标签: c pointers memory-leaks malloc

假设我的程序中有以下代码:

char *ptr;
ptr=malloc(sizeof(char)*10);
ptr=malloc(sizeof(char)*10);
ptr=malloc(sizeof(char)*10);
ptr=malloc(sizeof(char)*10);

每次都会将指向同一内存块的指针分配给ptr,或者每次保留一段单独的内存并将其指针分配给ptr,每次都会导致内存泄漏{ {1}}被称为?

我还在学习C,所以如果它太基础,请耐心等待。我尝试使用谷歌搜索,但没有找到答案。

修改::

感谢您的回答。请告诉我这种方法是否可以处理内存泄漏风险。我的程序只需要5个人的名字并显示它,而不使用静态数组。阅读完答案后,我把{ {1}}在循环内部,或者在我计划在循环之外只使用一次之后,在循环之后。我现在纠正了吗?

malloc()

7 个答案:

答案 0 :(得分:6)

malloc()将永远不会多次返回相同的内存块,除非(当然)自上次返回以来它已经free()。这是由C标准保证的。因此,您的代码也会泄漏内存。任何两次分配同一块内存的内存分配器都会比无用更糟糕:应用程序会自行使用相同的内存,可能会同时使用同一块内存。

编辑:禁止缓冲区溢出问题,您的代码是正确的,因为它释放了通过ptr引用的10-char缓冲区。在循环之外只调用一次free(ptr)确实是不正确的。但是,您的代码(如此处所示)不会释放稍后在names[i]中存储的循环体中分配的内存。

答案 1 :(得分:2)

是的,每个malloc调用都会分配一个新块,这意味着前一个块将被泄露。

编辑:回答问题的编辑部分

您现在正在释放ptr指向的块,但是您没有释放为names分配的块。你还需要:

for(i=0;i<=4;i++) {
   printf("%s\n",names[i]);
   free(names[i]);
}

在您的情况下,您可以跳过ptr并直接使用names。这是一个同样[un]安全的版本:

char *names[5];
int i;

for(i=0; i < 5; i++)
{
    names[i] = malloc(10);
    printf("Enter name no.%d : \n",i+1);
    scanf("%s",names[i]); // what if name is longer than 10 characters?
}

for(i=0; i < 5; i++)
{
   printf("%s\n",names[i]);
   free(names[i]);
}

但是,一旦进程退出,操作系统将回收进程消耗的内存,因此在这个简单的示例中您不必担心,但我想这只是一个例子。我还假设您不关心用户输入超过10个字符的名称,这些名称将覆盖已分配缓冲区的边界。

答案 2 :(得分:2)

每次都会分配一个单独的内存块,因为C不会执行任何垃圾回收,并且free次调用之间不会进行malloc次调用。前三个块被泄露,因为你没有保留指针。

您可以使用简单的printf调用自行查明指针是完全不同的:

for (int i = 0; i < 4; i++) {
    ptr = malloc(10);     // no need for sizeof(char), it's 1 by definition
    printf("%p\n", ptr);
}

这应打印四个不同的数字。

答案 3 :(得分:2)

假设每次调用成功,这将导致内存泄漏,除了分配给最后malloc的内存之外的所有内存都将无法访问。您需要为pointer分配的每个块保留malloc,或者在连续呼叫之间需要free。所以是的,malloc将尝试为每个呼叫分配不同的内存块。快速测试可以如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *ptr;
    ptr=malloc(sizeof(char)*10);
    printf("%p\n", ptr);
    ptr=malloc(sizeof(char)*10);
    printf("%p\n", ptr);
    ptr=malloc(sizeof(char)*10);
    printf("%p\n", ptr);
    ptr=malloc(sizeof(char)*10);
    printf("%p\n", ptr);
}

这将打印出每次分配的地址。如果您在每次调用free之间添加了malloc,则最终可能会使用相同的pointer,快速test会证明此行为。

答案 4 :(得分:1)

你的第二部分是正确的:这是一个内存泄漏。

答案 5 :(得分:1)

每次调用malloc时都会分配一个新的内存块。这将产生内存泄漏,因为您无法引用前三个分配来释放它们。

答案 6 :(得分:1)

您可以使用valgrind检查内存泄漏,它在检测内存泄漏方面非常有用。

valgrind ./progr