这是一个简单的程序,它将文件“hello.txt”读入一个动态分配的缓冲区,最初大小为10(填充时大小加倍)
运行valgrind时,似乎存在内存泄漏,但我不确定是什么问题。我在使用后释放了缓冲区的内存。
错误似乎是“条件跳转或移动取决于未初始化的值”
任何人都可以帮助确定是否存在内存泄漏?如果没有问题是什么?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFERSIZE 10
int main(int argc, char const *argv[])
{
FILE *source;
source = fopen("hello.txt","r");
char *buffer = (char *)malloc(BUFFERSIZE);
int current_size = BUFFERSIZE;
int len = 0;
char c;
while((c = fgetc(source)) != EOF)
{
if(len == current_size-1)
{
current_size *= 2;
buffer = (char *)realloc(buffer,current_size);
}
buffer[len] = c;
len++;
}
printf("%s",buffer);
free(buffer);
return 0;
}
答案 0 :(得分:3)
错误似乎是“条件跳转或移动取决于未初始化的值”
那你为什么要问内存泄漏?此错误的来源很可能是调用printf("%s", buffer)
buffer
不是有效字符串(无'\0'
终结符)。
您的代码的另一个问题是您将fgetc
的返回值分配给char
。您应该将char c
更改为int c
。
答案 1 :(得分:1)
如果这是valgrind抱怨,那是因为你要将realloc的返回值分配给你要重新分配的缓冲区。由于如果不能增加缓冲区,realloc将返回NULL,这可能导致缓冲区的新值被赋值为NULL并且旧值被泄露。
通常的比喻是这样的:
char * new_buffer = realloc(buffer, current_size);
if (!new_buffer) {
handle_error();
}
buffer = new_buffer;
C中的最佳做法是不从malloc或realloc转换返回。除了提及之外,不值得进入这里; SO有很多资源专门回答这个问题。
答案 2 :(得分:0)
在声明它们时,您缺少NULL检查并将指针初始化为NULL。
使用valgrind选项--track-origins=yes
让它跟踪未初始化值的来源。这会使速度变慢,但会帮助您追踪未初始化值的来源。
希望此选项可以帮助您解决任何此类问题。
答案 3 :(得分:0)
您需要使用临时指针:
char *temp = (char *)realloc(buffer,current_size);
if (!temp)
{
fprintf(stderr, "Out of memory...\n");
free(buffer);
exit(1);
}
buffer = temp;
编辑我还注意到你正在构建malloc和realloc - 这通常表明你正在使用C ++来编译C,这并不理想。如果您使用的是IDE,您可能需要设置它以便它使用C而不是C ++来编译代码 - 通常一种方法是将文件重命名为myfile.c而不是myfile.cpp - 您可能需要将其删除并重新添加到项目中以使更改生效。你可以通过施放malloc / realloc来获得一些非常讨厌的错误。
编辑: 您也没有在缓冲区中设置字符串的结束标记 - 您应该执行类似
的操作buffer[len] = '\0';
在你的while循环之后。请记住,如果文件也是空的,你可能在fgetc()中得到“无”,所以len可能为零。
您的原始malloc也应该检查NULL。
答案 4 :(得分:0)
出于好奇,我在你的代码片段上尝试了MemoryScape(TotalView)并且它没有显示任何内存泄漏(source
和buffer
变量是引用的块,这些内存块的含义地址可以在程序的当前变量数据中的某处找到。
我认为Valgrind肯定会在这里显示误报(我不知道场景后面有什么泄漏检测算法)。