【问题标题】:I have debug it for 4 hours,but I still can't find the BUG调试了4个小时还是找不到BUG
【发布时间】:2012-01-22 15:29:37
【问题描述】:

这个程序是从一个文件中输入一些字符串,然后将字符串一个一个地推入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]

【问题讨论】:

  • 调用 free() 后应该将 LineBuf 设置为 NULL
  • 4 小时对于发现错误来说并不算多;有些错误会花费你 4 周的时间!!!对于这个,valgrind 会帮助你。
  • @user1103180 请使用与代码更相关的问题标题

标签: c linux realloc freopen


【解决方案1】:

free(LineBuf) 正在释放内存,但稍后在调用 realloc 时再次使用 LineBuf。您应该在释放 LineBuf 后将其设置为 NULL,然后 realloc 将执行 malloc 而不是重新分配。请记住,在释放指针后将指针设置为 NULL 始终是一种好习惯。这有助于检测您是否使用指向已释放内存的指针。

顺便说一句,看看你的代码,我不太确定你打算做什么。根据您想要做什么,您可能会摆脱 LineBuf 或 fgets。另外:为每个 i 调用 strlen 性能不是很好,您最好检查一下 temp[i] != '\0'。

【讨论】:

  • 这个程序仅供测试~。我写了一个更大的程序,但是我发现PushToBuf函数有一些小问题,经过各种尝试,我复制了这个函数并编写一个小程序来修复我的代码。
【解决方案2】:

realloc ( void * ptr, size_t size ) 的工作原理:

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

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

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

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

  • 删除free()
  • 使用malloc 而不是realloc
  • free() 之后将LineBuf 设置为NULL。

【讨论】:

    【解决方案3】:

    您正在尝试 realloc 一个 free 的指针;你不能那样做!

    【讨论】:

      【解决方案4】:

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

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

      为了解决问题,将 free 移出 while 循环。并清空空闲缓冲区字节,将其存储的所有数据设置为空。

      for(int i =0; i

      【讨论】:

        猜你喜欢
        • 2020-03-06
        • 1970-01-01
        • 2018-01-29
        • 2011-03-09
        • 2012-03-13
        • 2013-11-06
        • 2022-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多