2
votes

Valgrind tells me, that there is a leak in a memory, I've tried to free() it but I suppose that it's not done properly. Any ideas? Thank You.

Invalid free() / delete / delete[] / realloc() at 0x4C27D4E: free (vg_replace_malloc.c:427)

by 0x400C00: main (main.c:149)

Address 0x51ba138 is 0 bytes after a block of size 8 alloc'd

at 0x4C28BED: malloc (vg_replace_malloc.c:263) by 0x400B0E: main (main.c:119)

HEAP SUMMARY: in use at exit: 2 bytes in 1 blocks total heap usage: 5 allocs, 5 frees, 14 bytes allocated

2 bytes in 1 blocks are definitely lost in loss record 1 of 1

at 0x4C28BED: malloc (vg_replace_malloc.c:263)

by 0x40084F: strdup (main.c:19)

by 0x4009C4: permute (main.c:83)

by 0x400B9C: main (main.c:138)

char *strdup (const char *s)
{
    char *d = malloc (strlen (s) + 1);  // Space for length plus null //line 19
    if (d == NULL) {
        return NULL;            // No memory
    }
    strcpy (d, s);              // Copy the characters
    return d;                   // Return the new string
}

void permute (char *arrayOfPermutations, int startIndex, int stopIndex,
            char ***permuts)
{
    int i;
    if (startIndex == stopIndex) {
        **permuts = strdup (arrayOfPermutations);       //save generated string //line 83
        *permuts += 1;          //increment location
    } else {
        for (i = startIndex; i <= stopIndex; i++) {
            swap ((arrayOfPermutations + startIndex),
                (arrayOfPermutations + i));
            permute (arrayOfPermutations, startIndex + 1, stopIndex, permuts);
            swap ((arrayOfPermutations + startIndex),
                (arrayOfPermutations + i));
        }
    }
}

int main (int argc, char *argv[])
{
    char *stringInput, c = 0;
    unsigned int j = 0, i = 0, stringSize, facto;
    char **permuts, **work;

    stringInput = (char *) malloc (sizeof (char));

    while (c != '\n') {
        c = getc (stdin);       //read the input from keyboard standard input
        stringInput = (char *) realloc (stringInput, (j + 1) * sizeof (char));  //re-allocate (resize) memory for character read to be stored
        stringInput[j] = c;     //store read character by making pointer point to c
        j++;
    }

    stringInput[j - 1] = '\0';  //add null termination
    stringSize = strlen (stringInput);
    facto = factorial (stringSize);

    permuts = (char **) malloc (facto * sizeof (char *));       // allocate n! pointers //line 119
    work = permuts;

    printf ("String size: %d\n", stringSize);

    ...some printfs here...permute (stringInput, 0, stringSize - 1, &work);     //creates permutations of chars //line 138

    qsort (permuts, facto, sizeof (char *), compare);   //sorts strings alphabetically

    for (i = 0; i <= facto - 1; i++) {
        printf ("\"%s\"\n", permuts[i]);
    }

    free (work);                //free the memory //line 149
    free (permuts);             //free the memory
    free (stringInput);         //free the memory
}
2
Is there any specific reason why you reimplement strdup if you're going to use string.h anyway (for strcpy)?Ingo Bürk
You are freeing twice the same memory: free(work) actually free the memory pointed by permutes, when you call free(permutes) you are freeing an invalid pointer.terence hill
strdup in not defined in my compiler's headers. Removing free(work) helped me, but I used for(i = 0; i <= facto-1; i++) { printf("\"%s\"\n", permuts[i]); free (permuts[i]); / free the text, allocated with strdup(); */ }insteadLuke

2 Answers

6
votes

Before I read your code. Valgrind reporting invalid free error is not because of leaked memory, but you try to free invalid memory (or free same memory more than once). Compiling your code with the compilter flag -g (gdb debug), will enable more debug information, making the backtraces from valgrind much better.

A quick guess:

  ..
  for(i = 0; i <= facto-1; i++)
   {
    printf("\"%s\"\n", permuts[i]);
    free (permuts[i]); /* free the text, allocated with strdup(); */
  }

  free(permuts);//free the memory
  free(stringInput);//free the memory
}
3
votes

Among other issues, a primary issue with your code is:

double free or corruption (out): 0x000000000074a060 ***

caused by:

char **permuts, **work;
...
work = permuts;
...
free (work);                //free the memory //line 149
free (permuts);             //free the memory

You are freeing the same block of memory twice.