0

I have a function that looks at a file of common passwords to see if any match the given encrypted password. If the password is in the set of common passwords, the program works, but if not I get an error message.

Even after some corrections, I get the following error message:

* Error in `./cs50': double free or corruption (out): 0x00007f9c7a061200 * Aborted

I seem to have a memory-leak somewhere preventing the program from continuing to the next step. Function code and valgrind output below.

Any advice?

bool check_common(char* pass, char* salt)
{
    FILE* fp = fopen("topps.txt", "r");
    if (fp == NULL) return false;

    char current_word[9];
    char* attempt = calloc(9, sizeof(char));
    while (fscanf(fp, "%s\n", current_word) != EOF)
    {
        // in case reads fewer than 8 chars
        for (int i=0;i<9;i++)
            if (current_word[i] != '\0')
                current_word[i] = '\0';

        attempt = crypt(current_word, salt);
        if (strcmp(pass, attempt) == 0)
        {
            printf("%s\n", current_word);
            fclose(fp);
            free(attempt);
            return true;
        }
    }

    free(attempt);
    fclose(fp);

    return false;
}

Valgrind output:

==22041== Invalid free() / delete / delete[] / realloc()
==22041==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22041==    by 0x4008F8: check_common (cs50.c:48)
==22041==    by 0x4009DD: main (cs50.c:123)
==22041==  Address 0x506f200 is 131200 bytes inside data symbol "_ufc_foobar"
==22041== 
Failed.
==22041== 
==22041== HEAP SUMMARY:
==22041==     in use at exit: 27 bytes in 3 blocks
==22041==   total heap usage: 4 allocs, 4 frees, 595 bytes allocated
==22041== 
==22041== 27 bytes in 3 blocks are definitely lost in loss record 1 of 1
==22041==    at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22041==    by 0x400864: check_common (cs50.c:34)
==22041==    by 0x4009DD: main (cs50.c:123)
==22041== 
==22041== LEAK SUMMARY:
==22041==    definitely lost: 27 bytes in 3 blocks
==22041==    indirectly lost: 0 bytes in 0 blocks
==22041==      possibly lost: 0 bytes in 0 blocks
==22041==    still reachable: 0 bytes in 0 blocks
==22041==         suppressed: 0 bytes in 0 blocks
==22041== 
==22041== For counts of detected and suppressed errors, rerun with: -v
==22041== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 0 from 0)
2
  • First let me point out that if the program finds the password in dictionary, it returns true, without freeing the attempt. Now with that freeing. I think the error probably comes from the free(attempt); command, and that's because of the char* attempt = calloc(1,9); command. Per the calloc's man page it's signature is void *calloc(size_t nmemb, size_t size);. So if you want 9 members of type char, you should probably use char* attempt = calloc(9, sizeof(char));. Try it and let me know if it worked.
    – ChrisG
    Commented Aug 4, 2015 at 18:33
  • Thanks for your first point - I should have caught that. But that and your other good suggestion don't seem to work. Revised code and valgrind output above.
    – L.B.
    Commented Aug 4, 2015 at 20:55

1 Answer 1

1

I think I solved it. It seems that I was overwriting my pointer to my allocated memory with another pointer (when I assigned attempt the output of the crypt function (another pointer - to the encoded string)) after calloc'ing attempt, which leaks it. I then tried to free the pointer I received from crypt, which is invalid, as valgrind said (see more here).

Here is my revised code:

bool check_common(char* pass, char* salt)
{
    FILE* fp = fopen("topps.txt", "r");
    if (fp == NULL) return false;

    char current_word[9];
    while (fscanf(fp, "%s\n", current_word) != EOF)
    {
        char* attempt = crypt(current_word, salt);
        if (strcmp(pass, attempt) == 0)
        {
            printf("%s\n", current_word);
            fclose(fp);
            return true;
        }
    }

    fclose(fp);

    return false;
}

You must log in to answer this question.

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