假设我的程序中有以下代码:
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()
答案 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