为什么我会收到“double free or corruption”内存访问错误?

13

我遇到了以下类型的错误。我知道这与我不正确地访问内存有关,但我不知道具体是哪里出了问题。请帮助我找出我的错误所在。

*注意:我已经简化了我的函数,并且其中变量的作用并不明显,我只需要知道我如何实现函数不正确或者我在哪里误用了内存访问。

int my_function(char const *file_name, size_t max)
        {

        myStruct.pStore = fopen(file_name,"w+");      //pStore is a FILE* 
        myStruct.max = max;                 

        // fill the with zeros ('0')
        int numberOfZeros = max*SIZE;
        char zeros[numberOfZeros];                      

        int i=0;
        while(i<numberOfZeros)         // insert zero's 
        {
                zeros[i]='0';
                i++;
        }
        fwrite(zeros,sizeof(char),numberOfZeros,myStruct.pStore);
        fclose(myStruct.pStore);

        return EXIT_SUCCESS; 

我收到的错误信息:

*** glibc detected *** /home/.../: double free or corruption (top): 0x0804c008 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x73e42)[0xb7e82e42]
/lib/i386-linux-gnu/libc.so.6(fclose+0x154)[0xb7e72384]
/home/2012/spatar/cs/specs/release[0x80486b0]
/home/2012/spatar/cs/specs/release[0x8048acd]
/home/2012/spatar/cs/specs/release[0x8048af0]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb7e284d3]
/home/2012/spatar/cs/specs/release[0x80484e1]
 ======= Memory map: ========
08048000-0804a000 r-xp 00000000 00:3b 2331829    /home/2012/spatar/cs/Aspecs/release
0804a000-0804b000 r--p 00001000 00:3b 2331829    /home/2012/spatar/cs/specs/release
0804b000-0804c000 rw-p 00002000 00:3b 2331829    /home/2012/spatar/cs/specs/release
0804c000-0806d000 rw-p 00000000 00:00 0          [heap]
b7e0e000-b7e0f000 rw-p 00000000 00:00 0 
b7e0f000-b7fae000 r-xp 00000000 00:11 5415       /lib/i386-linux-gnu/libc-2.15.so
b7fae000-b7fb0000 r--p 0019f000 00:11 5415       /lib/i386-linux-gnu/libc-2.15.so
b7fb0000-b7fb1000 rw-p 001a1000 00:11 5415       /lib/i386-linux-gnu/libc-2.15.so
b7fb1000-b7fb4000 rw-p 00000000 00:00 0 
b7fbc000-b7fd8000 r-xp 00000000 00:11 5426       /lib/i386-linux-gnu/libgcc_s.so.1
b7fd8000-b7fd9000 r--p 0001b000 00:11 5426       /lib/i386-linux-gnu/libgcc_s.so.1
b7fd9000-b7fda000 rw-p 0001c000 00:11 5426       /lib/i386-linux-gnu/libgcc_s.so.1
b7fda000-b7fdd000 rw-p 00000000 00:00 0 
b7fdd000-b7fde000 r-xp 00000000 00:00 0          [vdso]
b7fde000-b7ffe000 r-xp 00000000 00:11 5405       /lib/i386-linux-gnu/ld-2.15.so
b7ffe000-b7fff000 r--p 0001f000 00:11 5405       /lib/i386-linux-gnu/ld-2.15.so
b7fff000-b8000000 rw-p 00020000 00:11 5405       /lib/i386-linux-gnu/ld-2.15.so
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]

1
展示你释放内存的代码部分。 - Ramy Al Zuhouri
3
使用调试器。使用调试器。使用调试器。 - Jim Balter
1
由于此函数既不通过malloc()free()分配内存,也不释放内存,因此这个函数很可能不是问题的直接原因。它也不清楚是否调用了任何可能引起问题的内容。我建议尝试valgrind - Jonathan Leffler
2
如果在my_function()之外再次使用fclose()关闭同一个文件,你可能会遇到这个问题。 - Alexey Frunze
numberOfZeros有多大?如果它足够大,你可能会溢出堆栈并破坏内存。你真的需要提供更多的示例代码(易于编译)和参数来重现问题。这样你会得到更好的帮助。 - James
显示剩余5条评论
2个回答

13

看起来你试图释放已经被释放或者被取消引用的内存。

将你的程序与efence链接或者用valgrind运行它。

这将告诉你指针被取消引用的位置。


我正在使用gdb,这些更好吗? - spatara
只需发布您释放内存的部分,我们就可以在两分钟内找到错误。 - Ramy Al Zuhouri

7

内存损坏通常是由于在分配的内存末尾之外写入数据造成的,而且通常只是因为某人忘记添加一个字节以终止字符串所需的空字符。

双重释放意味着使用相同的x值两次调用free(x)。 在您的代码中的某个位置调用了free(x),然后很可能在另一段代码中再次调用了free(x)。

隔离问题的最简单方法是使用gdb并观察您逐步执行代码时发生的情况。

在上面的my_function代码中,没有调用malloc或free。 zeros缓冲区位于堆栈上,而while循环不会超出缓冲区的末尾。 问题在于代码的其他部分。修复问题需要多长时间取决于从多少个地方调用malloc/free/strdup等函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接