我调试了4个小时,还是找不到BUG

发布于 2024-12-21 11:51:18 字数 1356 浏览 3 评论 0原文

这个程序是从文件中输入一些字符串,然后将字符串一一压入LineBuf,当我们将一个字符串压入LineBuf后,打印LineBuf strong>,然后将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]

This is program is input some string from a file, then, push strings into LineBuf one by one, after we push one string into LineBuf, print LineBuf,then, make LineBuf empty.

This is my code:

#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 my input stream:

This is a test. Good evening
bye~

This is run result:

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]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

平定天下 2024-12-28 11:51:18

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

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

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

在您的情况下,指针已经被释放,但仍然不是 NULL,因此当程序尝试移动此内存块时,它会导致内存损坏。

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

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

How realloc ( void * ptr, size_t size ) works:

The size of the memory block pointed to by the ptr parameter is
changed to the size bytes, expanding or reducing the amount of memory
available in the block. The function may move the memory block to a new location, in which
case the new location is returned.

In case that ptr is NULL, the function behaves exactly as malloc,
assigning a new block of size bytes and returning a pointer to the
beginning of it.

In your case the pointer is already freed, but still isn't NULL, so when the program tries to move this memory block, it causes memory corruption.

To solve it, you should do one of the following:

  • Remove free().
  • Use malloc instead of realloc.
  • Set LineBuf to NULL after free().
茶底世界 2024-12-28 11:51:18

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

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

要解决这个问题,请将 free 移出 while 循环。并通过将其存储的所有数据设置为空来清空空闲缓冲区。

for(int i =0; i < BuffLen)
LineBuf[i]='\0';

This does not make LineBuf empty. It free the storage space for LineBuf. When you later realloc LineBuff it attemps to realloc freed space.

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

to solve the provlem move the free out of the while loop. and empty free buff byt setting all of the data it stores to null.

for(int i =0; i < BuffLen)
LineBuf[i]='\0';

素染倾城色 2024-12-28 11:51:18

您正在尝试重新分配一个释放的指针;你不能那样做!

You're trying to realloc a free'd pointer; you can't do that!

小忆控 2024-12-28 11:51:18

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

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

free(LineBuf) is freeing the memory, but you are using LineBuf again later when calling realloc. You should set LineBuf to NULL after freeing it, then the realloc will do malloc and not reallocate. Keep in mind, it is always good practice to set pointers to NULL after freeing them. This helps detect if you are using pointers to freed memory.

BTW, looking at your code I am not quite sure what you intend to do. Depending on what you want to do you might get rid of LineBuf or of fgets. Also: calling strlen for every i is not very performant, you might better check for temp[i] != '\0'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文