分配还是不分配。大小 1 错误的读取无效。 【凝视2小时】

To allocate or not to allocate. Invalid read of size 1 errors. [Staring for 2 hours]

这是我正在处理的代码

code

但是也有问题。部分或全部可能是因为在节点(第 135~ 行)中没有为 data 分配 space,因为 linemain 的迭代过程中发生了变化。但是当我为它分配 space 时,在第 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)

在第 138 行,如果条件为假(无法为字符串分配 space),那么您忘记了 return,即:

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

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

第一次释放 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;
}