Search code examples
cfreevalgrindrealloc

Why does Valgrind reports an invalid free() after a realloc()?


When I run valgrind on the following (example) code it reports an "Invalid free() / delete / delete[]" and Invalids reads. I really can't understand why. Can somebody please explain ?

Edit : Thanks for your replies, it's so obvious now.

#include <stdio.h>
#include <stdlib.h>
#include <string.h

void vl_dec(char* a) {
  char* str = a;
  while (*(str+1) != '\0') str++;
  while(*str == '0') {
    *str = '9';
    str--;
  }
  (*str)--;

  if (*a == '0') {
    memmove(a, a+1, strlen(a));
    a = (char*)realloc(a, (strlen(a)+1)*sizeof(char));
    if (a == NULL) {
      fprintf(stderr, "Cannot allocate memory\n");
      exit(1);
    }
  }
}

int main(int argc, char* argv[]) {
  char* a = (char*)malloc(6*sizeof(char));
  if (a == NULL) {
    fprintf(stderr, "Cannot allocate memory\n");
    exit(1);
  }
  strcpy(a, "10000");
  vl_dec(a);
  printf("%s\n", a);
  free(a);
  return 0;
}

Solution

  • In your function main, you are passing a to vl_dec by value, so it never gets updated - the result of realloc is only stored in a local variable that's lost when vl_dec returns. Instead, pass its address:

    void vl_dec(char ** a) { *a = realloc(...); }
    
    int main()
    {
        char * a = malloc(...);
        vl_dec(&a);
        free(a);
    }