【问题标题】:To allocate or not to allocate. Invalid read of size 1 errors. [Staring for 2 hours]分配或不分配。大小为 1 的错误读取无效。 [凝视2小时]
【发布时间】:2015-02-11 18:17:59
【问题描述】:

这是我正在处理的代码

code

但是有问题。部分或全部可能是因为没有在节点中为data 分配空间(第135 行~),因为linemain 的迭代过程中发生了变化。但是当我为它分配空间时,在第 135 行,结果并没有太大变化,并且存在内存泄漏。我被卡住了。

我快疯了。你能帮我解决错误吗?

感谢任何帮助。谢谢!

输出:

a@ubuntu:~/os/hw1$ ./o f1.txt f2.txt o.txt
*** Error in `./o': double free or corruption (fasttop): 0x0000000001e8b250 ***
Aborted (core dumped)

瓦尔格林:

a@ubuntu:~/os/hw1$ valgrind --leak-check=full ./o f1.txt f2.txt o.txt
==21643== Memcheck, a memory error detector
==21643== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==21643== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==21643== Command: ./o f1.txt f2.txt o.txt
==21643== 
==21643== Invalid write of size 2
==21643==    at 0x4C2F843: __GI_memcpy (vg_replace_strmem.c:917)
==21643==    by 0x4EA5ED7: getdelim (iogetdelim.c:115)
==21643==    by 0x400959: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c0 is 0 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid write of size 1
==21643==    at 0x4EA5FD4: getdelim (iogetdelim.c:122)
==21643==    by 0x400959: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c2 is 2 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 1
==21643==    at 0x4EC28BC: strtok (strtok.S:137)
==21643==    by 0x40092F: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c0 is 0 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 1
==21643==    at 0x4EC28EC: strtok (strtok.S:163)
==21643==    by 0x40092F: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c0 is 0 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 1
==21643==    at 0x4EC28F3: strtok (strtok.S:167)
==21643==    by 0x40092F: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c1 is 1 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid write of size 1
==21643==    at 0x4EC2919: strtok (strtok.S:186)
==21643==    by 0x40092F: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c1 is 1 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 1
==21643==    at 0x4C2EC31: strcmp (vg_replace_strmem.c:755)
==21643==    by 0x400A67: insert (in /home/a/os/hw1/o)
==21643==    by 0x400942: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c0 is 0 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 1
==21643==    at 0x4C2DB62: strlen (vg_replace_strmem.c:412)
==21643==    by 0x4EBF66D: strdup (strdup.c:41)
==21643==    by 0x400ABB: insert (in /home/a/os/hw1/o)
==21643==    by 0x400942: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c0 is 0 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 1
==21643==    at 0x4C2DB74: strlen (vg_replace_strmem.c:412)
==21643==    by 0x4EBF66D: strdup (strdup.c:41)
==21643==    by 0x400ABB: insert (in /home/a/os/hw1/o)
==21643==    by 0x400942: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c1 is 1 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 2
==21643==    at 0x4C2F840: __GI_memcpy (vg_replace_strmem.c:917)
==21643==    by 0x400ABB: insert (in /home/a/os/hw1/o)
==21643==    by 0x400942: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c0 is 0 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid read of size 1
==21643==    at 0x4C2EC48: strcmp (vg_replace_strmem.c:755)
==21643==    by 0x400A67: insert (in /home/a/os/hw1/o)
==21643==    by 0x400942: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c1 is 1 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== Invalid free() / delete / delete[] / realloc()
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x400985: main (in /home/a/os/hw1/o)
==21643==  Address 0x51fc2c0 is 0 bytes inside a block of size 120 free'd
==21643==    at 0x4C2BCD7: free (vg_replace_malloc.c:473)
==21643==    by 0x4008F6: main (in /home/a/os/hw1/o)
==21643== 
==21643== 
==21643== HEAP SUMMARY:
==21643==     in use at exit: 0 bytes in 0 blocks
==21643==   total heap usage: 10 allocs, 11 frees, 1,878 bytes allocated
==21643== 
==21643== All heap blocks were freed -- no leaks are possible
==21643== 
==21643== For counts of detected and suppressed errors, rerun with: -v
==21643== ERROR SUMMARY: 22 errors from 12 contexts (suppressed: 0 from 0)

【问题讨论】:

  • if(newPtr->data == NULL) free(newPtr); 然后您立即取消引用 free()d 指针。释放后必须从函数中返回。
  • 认真的吗? strtok(line, "\n");,只是 if (line[read - 1] == '\n') line[--read] = '\0'; 会更好,更明确。不要误会,我认为你会成为一名出色的程序员。
  • @iharob:我没有通读代码来查找上下文,但是您的第三点具有不同的语义 --- 它将值复制到 ptr 之前指向的任何位置(而不是只是改变ptr)。
  • @TimČas 绝对正确,我正在删除评论。
  • 首先有一个代码链接;然后是代码;现在两者都没有。那么我们在这里调试什么?

标签: c memory-leaks valgrind


【解决方案1】:

在您第一次释放line 后,您应该将其设置为NULL 并将len 设置为0

if (line)
    free(line);
line = NULL; /* make it NULL so you can call getline() again or just don't free it yet */
len  = 0;

否则,对getline() 的后续调用将尝试访问无效指针。

另外,正如我评论的那样

if(newPtr->data == NULL)
    free(newPtr);

错了,因为无论如何你都会取消引用newPtr,所以你必须

if (newPtr->data == NULL)
{
    free(newPtr);
    return;
}

【讨论】:

  • 很好 - 并设置len = 0
  • @WeatherVane 我不记得是否需要,让我查看手册。
  • @WeatherVane 也不错,但手册说如果第一个参数是 NULL*n 值将被忽略。
  • 对不起,我在哪里看到了两者都说!
  • @WeatherVane 好的,然后添加它。
【解决方案2】:

在第 138 行,如果条件为假(无法为字符串分配空间)那么您忘记返回,即:

if(newPtr->data == NULL) {
    free(newPtr);
    return;
}

如果发生这种情况,肯定会导致内存问题。可能还有其他问题(还在寻找中……)

【讨论】:

  • @WeatherVane 因为原始代码在一个链接上,我复制了它并格式化并粘贴在这里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
  • 2015-05-09
  • 2020-08-19
  • 2014-04-19
相关资源
最近更新 更多