繁体   English   中英

读入缓冲区时发生内存泄漏

[英]Memory leak when reading into buffer

这是一个简单的程序,可将文件“ 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;
}

错误似乎是“有条件的跳跃或移动取决于未初始化的值”

那你为什么要问内存泄漏呢? 此错误的根源很可能是对printf("%s", buffer)的调用printf("%s", buffer)其中buffer不是有效的字符串(没有'\\0'终止符)。

代码的另一个问题是,您正在将fgetc的返回值分配给char 您应该将char c更改为int c

如果这是valgrind抱怨,那么这样做是因为您将realloc的返回值分配给了要重新分配的缓冲区。 由于如果重新分配不能增长缓冲区,则realloc将返回NULL,因此这可能导致将缓冲区的新值分配给NULL,而旧值被泄漏。

通常的隐喻是这样的:

char * new_buffer = realloc(buffer, current_size);
if (!new_buffer) {
    handle_error();
}
buffer = new_buffer;

同样,C语言中的最佳实践是不强制从malloc或realloc返回。 除了提及它,不值得进入这里。 因此,SO有很多资源专门用于解决此问题。

您缺少NULL检查,并且在声明它们时初始化了指向NULL的指针。

使用valgrind选项--track-origins=yes可以跟踪未初始化值的来源。 这将使其变慢,但将帮助您跟踪未初始化值的来源。

希望此选项将来可以帮助您解决任何此类问题。

您需要使用一个临时指针:

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。

出于好奇,我在您的代码段上尝试使用MemoryScape(TotalView),它没有显示任何内存泄漏( source变量和buffer变量是引用的块,这意味着这些内存块的地址可以在程序的当前变量数据中找到)。

我认为Valgrind在这里肯定显示出误报(我不知道幕后是什么泄漏检测算法)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM