1

当我在以下(示例)代码上运行 valgrind 时,它会报告“Invalid free() / delete / delete[]”和 Invalids 读取。我真的不明白为什么。有人可以解释一下吗?

编辑:感谢您的回复,现在很明显。

#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;
}
4

3 回答 3

3

在您的 functionmain中,您是按值传递avl_dec,因此它永远不会被更新 - 结果realloc仅存储在vl_dec返回时丢失的局部变量中。相反,传递它的地址:

void vl_dec(char ** a) { *a = realloc(...); }

int main()
{
    char * a = malloc(...);
    vl_dec(&a);
    free(a);
}
于 2012-05-06T22:26:01.567 回答
1

您不能只假设返回的新值arealloc旧值相同。您实际上必须在每个使用它的地方更新指针。我怀疑您知道这一点,因为您正确保存了reallocinside of的返回值vl_dec,但是您忘记了需要返回afrom的新值vl_dec(或通过使用 achar**作为参数来更新它 to vl_dec。)

于 2012-05-06T22:27:16.150 回答
0

因为您通过vl_dec值而不是通过引用传递指针。

如果您的main 函数中realloc的指针仍然会看到 main 中声明的原始指针。vl_decrealloc该指针无效之后,valgrind 抱怨。

解决此问题的一种简单方法是重写vl_dec并让它返回指针。这样你就可以调用:

   a = vl_dec(a);

主要是问题解决了。

于 2012-05-06T22:27:52.203 回答