0

Having implemented the functions within dictionary.c, I tried running speller.c but was given the error double free or corruption (!prev). And so I ran speller.c through valgrind and got the message below:

==1812== Invalid read of size 8
==1812== at 0x4011C2: load (dictionary.c:93)
==1812== by 0x40087D: main (speller.c:45)
==1812== Address 0x59fbfd0 is not stack'd, malloc'd or (recently) free'd
==1812==
==1812== Invalid write of size 8
==1812== at 0x4011F5: load (dictionary.c:95)
==1812== by 0x40087D: main (speller.c:45)
==1812== Address 0x59fbfd0 is not stack'd, malloc'd or (recently) free'd
==1812==
==1812== Invalid read of size 8
==1812== at 0x40120B: load (dictionary.c:96)
==1812== by 0x40087D: main (speller.c:45)
==1812== Address 0x59fbfd0 is not stack'd, malloc'd or (recently) free'd
==1812==
==1812== Invalid read of size 8
==1812== at 0x4012E0: unloader (dictionary.c:130)
==1812== by 0x401350: unload (dictionary.c:148)
==1812== by 0x400D6D: main (speller.c:157)
==1812== Address 0x51fc3f0 is 16 bytes inside a block of size 224 free'd
==1812== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64- linux.so) ==1812== by 0x40132C: unloader (dictionary.c:140)
==1812== by 0x401308: unloader (dictionary.c:133)
==1812== by 0x401350: unload (dictionary.c:148)
==1812== by 0x400D6D: main (speller.c:157)
==1812==
==1812== Invalid free() / delete / delete[] / realloc()
==1812== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1812== by 0x40132C: unloader (dictionary.c:140)
==1812== by 0x401350: unload (dictionary.c:148)
==1812== by 0x400D6D: main (speller.c:157)
==1812== Address 0x51fc3e0 is 0 bytes inside a block of size 224 free'd
==1812== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64- linux.so)
==1812== by 0x40132C: unloader (dictionary.c:140)
==1812== by 0x401308: unloader (dictionary.c:133)
==1812== by 0x401350: unload (dictionary.c:148)
==1812== by 0x400D6D: main (speller.c:157)
==1812==

WORDS MISSPELLED: 19190
WORDS IN DICTIONARY: 0
WORDS IN TEXT: 19190
TIME IN load: 5.80
TIME IN check: 0.04
TIME IN size: 0.00
TIME IN unload: 0.32
TIME IN TOTAL: 6.15

==1812==
==1812== HEAP SUMMARY:
==1812== in use at exit: 321,638,808 bytes in 1,435,886 blocks
==1812== total heap usage: 1,435,888 allocs, 3 frees, 321,639,600 bytes allocated ==1812==
==1812== 87,578,176 bytes in 390,974 blocks are possibly lost in loss record 4 of 6
==1812== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1812== by 0x4011E3: load (dictionary.c:95)
==1812== by 0x40087D: main (speller.c:45)
==1812==
==1812== 227,535,840 (1,792 direct, 227,534,048 indirect) bytes in 8 blocks are definitely lost in loss record 6 of 6
==1812== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1812== by 0x4011E3: load (dictionary.c:95)
==1812== by 0x40087D: main (speller.c:45)
==1812==
==1812== LEAK SUMMARY:
==1812== definitely lost: 1,792 bytes in 8 blocks
==1812== indirectly lost: 227,534,048 bytes in 1,015,777 blocks
==1812== possibly lost: 87,578,176 bytes in 390,974 blocks
==1812== still reachable: 6,524,792 bytes in 29,127 blocks
==1812== suppressed: 0 bytes in 0 blocks
==1812== Reachable blocks (those to which a pointer was found) are not shown.
==1812== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1812==
==1812== For counts of detected and suppressed errors, rerun with: -v
==1812== ERROR SUMMARY: 52 errors from 7 contexts (suppressed: 0 from 0)ssed: 0 from 0)

What I don't get is simply checking if whatever children is pointing to is NULL
(like this: if (ptr->children[c - 'a'] == NULL)) could result in a memory leak.

Here is my code: http://pastebin.com/1ySftEDH

Any help/advice would be greatly appreciated!


EDIT: Made a few adjustments to my code, mainly in check() and the recursive function that unload() calls. Running speller.c no longer produces the double free or corruption (!prev) error. Instead I get a segmentation fault. Could someone point me in the right direction?

Updated code: http://pastebin.com/dV0EtmXD

==3091== Invalid read of size 8
==3091== at 0x4012C2: load (dictionary.c:109)
==3091== by 0x40087D: main (speller.c:45)
==3091== Address 0x59fbfd0 is not stack'd, malloc'd or (recently) free'd
==3091==
==3091== Invalid write of size 8
==3091== at 0x4012F5: load (dictionary.c:111)
==3091== by 0x40087D: main (speller.c:45)
==3091== Address 0x59fbfd0 is not stack'd, malloc'd or (recently) free'd
==3091==
==3091== Invalid read of size 8
==3091== at 0x40130B: load (dictionary.c:112)
==3091== by 0x40087D: main (speller.c:45)
==3091== Address 0x59fbfd0 is not stack'd, malloc'd or (recently) free'd
==3091==
==3091== Invalid read of size 8
==3091== at 0x401145: check (dictionary.c:67)
==3091== by 0x400C07: main (speller.c:117)
==3091== Address 0x51fc3c8 is 24 bytes before a block of size 224 alloc'd
==3091== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3091== by 0x4012E3: load (dictionary.c:111)
==3091== by 0x40087D: main (speller.c:45)
==3091==
==3091== Invalid read of size 8
==3091== at 0x4010DF: check (dictionary.c:55)
==3091== by 0x400C07: main (speller.c:117)
==3091== Address 0x28 is not stack'd, malloc'd or (recently) free'd
==3091==
==3091==
==3091== Process terminating with default action of signal 11 (SIGSEGV)
==3091== Access not within mapped region at address 0x28
==3091== at 0x4010DF: check (dictionary.c:55)
==3091== by 0x400C07: main (speller.c:117)
==3091== If you believe this happened as a result of a stack
==3091== overflow in your program's main thread (unlikely but
==3091== possible), you can try to increase the size of the
==3091== main thread stack using the --main-stacksize= flag.
==3091== The main thread stack size used in this run was 8388608.
==3091==
==3091== HEAP SUMMARY:
==3091== in use at exit: 321,639,600 bytes in 1,435,888 blocks
==3091== total heap usage: 1,435,888 allocs, 0 frees, 321,639,600 bytes allocated
==3091==
==3091== 87,578,176 bytes in 390,974 blocks are possibly lost in loss record 5 of 7
==3091== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3091== by 0x4012E3: load (dictionary.c:111)
==3091== by 0x40087D: main (speller.c:45)
==3091==
==3091== 227,535,840 (1,792 direct, 227,534,048 indirect) bytes in 8 blocks are definitely lost in loss record 7 of 7
==3091== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3091== by 0x4012E3: load (dictionary.c:111)
==3091== by 0x40087D: main (speller.c:45)
==3091==
==3091== LEAK SUMMARY:
==3091== definitely lost: 1,792 bytes in 8 blocks
==3091== indirectly lost: 227,534,048 bytes in 1,015,777 blocks
==3091== possibly lost: 87,578,176 bytes in 390,974 blocks
==3091== still reachable: 6,525,584 bytes in 29,129 blocks
==3091== suppressed: 0 bytes in 0 blocks
==3091== Reachable blocks (those to which a pointer was found) are not shown.
==3091== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==3091==
==3091== For counts of detected and suppressed errors, rerun with: -v
==3091== ERROR SUMMARY: 28 errors from 7 contexts (suppressed: 0 from 0)
Segmentation fault


EDIT 1: Made some more changes to my code. Fixed the logic error in load() by making it check for apostrophes. Down to 1 error in valgrind.

==2143== Invalid write of size 1
==2143== at 0x4013D7: load (dictionary.c:134)
==2143== by 0x40087D: main (speller.c:45)
==2143== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2143==
==2143==
==2143== Process terminating with default action of signal 11 (SIGSEGV)
==2143== Access not within mapped region at address 0x0
==2143== at 0x4013D7: load (dictionary.c:134)
==2143== by 0x40087D: main (speller.c:45)
==2143== If you believe this happened as a result of a stack
==2143== overflow in your program's main thread (unlikely but
==2143== possible), you can try to increase the size of the
==2143== main thread stack using the --main-stacksize= flag.
==2143== The main thread stack size used in this run was 8388608.
==2143==
==2143== HEAP SUMMARY:
==2143== in use at exit: 1,016 bytes in 3 blocks
==2143== total heap usage: 3 allocs, 0 frees, 1,016 bytes allocated
==2143==
==2143== LEAK SUMMARY:
==2143== definitely lost: 0 bytes in 0 blocks
==2143== indirectly lost: 0 bytes in 0 blocks
==2143== possibly lost: 0 bytes in 0 blocks
==2143== still reachable: 1,016 bytes in 3 blocks
==2143== suppressed: 0 bytes in 0 blocks
==2143== Reachable blocks (those to which a pointer was found) are not shown.
==2143== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==2143==
==2143== For counts of detected and suppressed errors, rerun with: -v
==2143== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

Updated code: http://pastebin.com/57a2HPMg

1 Answer 1

0

The double free is happening during your unloader() call. Look at the following:

    if (ptr->children[i] != NULL)
    {
        ptr = ptr->children[i];
        unloader(ptr);
    }

This will recursively call unloader(), but it causes a problem on return. When it returns to the parent level, it is no longer processing the current level of the trie, it's one level down because of the reassignment of ptr. Instead, it should use the children pointer directly in the call.

        unloader(ptr->children[i]);

This way, the code isn't moving from parent to child level in the current loop.

That clears out the double free and a large part of the memory leaks. The remaining memory leaks exist because of a logic error. The code works fine for letters, but there is nothing in the code to handle apostrophes. That's a big problem. Since you haven't had a chance to deal with this, I'll leave it to you to try to fix it first. ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

4
  • Thank you for pointing that out! I had to re-look at unloader() a few times in order to get that. On another note, what would the logic error be referring to? Because I'm still trying to figure out Valgrind's first few error messages
    – user1742
    Jun 11, 2016 at 19:02
  • "The remaining memory leaks exist because of a logic error. The code works fine for letters, but there is nothing in the code to handle apostrophes." Also, while valgrind might give clues, it is best not to work on memory leaks until the program is working correctly. Fixing malfunctions in the code often also clear memory leaks.
    – Cliff B
    Jun 11, 2016 at 19:27
  • Noted, thanks. I tried addressing those issues and made some changes to my code. Just checking, what do the error messages mean (and how do I know what they are trying to say?)
    – user1742
    Jun 11, 2016 at 20:45
  • Ok, I saw the logic error already. Thanks!
    – user1742
    Jun 12, 2016 at 10:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .