我调试了4个小时,但我仍然找不到BUG

时间:2011-12-17 14:37:58

标签: c linux realloc freopen

这是程序从文件输入一些字符串,然后,在我们将一个字符串推入 LineBuf 后,逐个将字符串推入 LineBuf ,打印然后,LineBuf 使 LineBuf 为空。

这是我的代码:

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

char *LineBuf = NULL;
int BufLen = 0;

void PushToBuf(char c)
{
    LineBuf = (char *)realloc(LineBuf, (BufLen+2)*sizeof(char));
    LineBuf[BufLen] = c;
    BufLen++;
    LineBuf[BufLen] = '\0';
}

int main()
{
    char temp[20];
    int i;
    FILE *fp;
    fp = fopen("input", "r");

    while (fgets(temp, 20, fp) > 0)
    {
        /*Push temp into buf*/
        for (i = 0; i < strlen(temp); i++)
            PushToBuf(temp[i]);

        /*print buf*/
        printf("%s\n", LineBuf);
        printf("%d\n", BufLen);

        /*make buf empty*/
        free(LineBuf);
        BufLen = 0;
    }
    return 0;
}

这是我的输入流:

This is a test. Good evening
bye~

这是运行结果:

This is a test file
19
. Good evening

15
 glibc detected  ./a.out: double free or corruption (fasttop): 0x00000000023fa250 

======= Backtrace: =========

/lib/libc.so.6(+0x775b6)[0x7f2ad01bf5b6]
/lib/libc.so.6(cfree+0x73)[0x7f2ad01c5e83]
./a.out[0x400868]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f2ad0166c4d]
./a.out[0x400699]

4 个答案:

答案 0 :(得分:1)

这不会使LineBuf变空。它释放了LineBuf的存储空间。当您稍后重新分配LineBuff时,它会尝试重新分配释放的空间。

    /*make buf empty*/
    free(LineBuf);

解决问题,移出while循环。和空的自由buff将它存储的所有数据设置为null。

for(int i = 0; i&lt; BuffLen)     LineBuf [I] = '\ 0';

答案 1 :(得分:1)

您正试图realloc free'指针;你做不到!

答案 2 :(得分:1)

realloc ( void * ptr, size_t size )如何运作:

  

ptr参数指向的内存块大小为   更改为size字节,扩展或减少内存量   块中可用。该功能可以将存储块移动到新的位置,其中   如果返回新位置。

     

如果ptrNULL,则该函数的行为与malloc完全相同,   分配一个新的size字节块并返回指向该字节的指针   开始吧。

在你的情况下,指针已经被释放,但仍然不是NULL,所以当程序试图移动这个内存块时,它会导致内存损坏。

要解决此问题,您应该执行以下操作之一:

  • 删除free()
  • 使用malloc代替realloc
  • LineBuf
  • 之后将free()设置为NULL

答案 3 :(得分:0)

free(LineBuf)正在释放内存,但是稍后在调用realloc时再次使用LineBuf。释放后应将LineBuf设置为NULL,然后realloc将执行malloc而不是重新分配。请记住,在释放它们之后将指针设置为NULL总是很好的做法。这有助于检测您是否使用指针释放内存。

顺便说一下,看看你的代码,我不太清楚你打算做什么。根据您的想法,您可能会摆脱LineBuf或fgets。另外:每次调用strlen都不是很有效,你最好检查一下temp [i]!=&#39; \ 0&#39;。