简体   繁体   English

为什么Valgrind在realloc()之后报告无效的free()?

[英]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. 当我在以下(示例)代码上运行valgrind时,它报告“无效的free()/ delete / delete []”和Invalids读取。 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;
}

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. 在你的函数main ,要传递avl_dec的价值,所以它永远不会被更新-结果realloc只存储在失去了当一个局部变量vl_dec回报。 Instead, pass its address: 相反,传递其地址:

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

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

You can't just assume that the new value of a that realloc returns is the same as the old value. 你不能只是假设的新价值arealloc回报是一样的旧值。 You actually have to update the pointer every where it's used. 实际上,您必须在每次使用它的地方更新指针。 I suspect you know that, because you correctly saved the return value of realloc inside of vl_dec , however you forgot that you need to return the new value of a from vl_dec (or update it by using a char** as the paramter to vl_dec .) 我怀疑你知道,因为你正确保存的返回值reallocvl_dec ,但是你忘记了你需要返回的新值avl_dec (或使用更新char**作为参数设置为vl_dec 。 )

because you pass the pointer to vl_dec by value, not by reference. 因为您通过值将指针传递给vl_dec ,而不是通过引用传递。

If you realloc the pointer within vl_dec your main function will still see the original pointer declared in main. 如果您realloc内的指针vl_dec你的主要功能仍然会看到在主声明的原始指针。 After realloc that pointer is invalid, so valgrind complains. realloc指针无效后,valgrind抱怨。

A easy way to fix this is to rewrite vl_dec and let it return the pointer. 解决这个问题的一个简单方法是重写vl_dec并让它返回指针。 That way you can call: 那样你就可以打电话:

   a = vl_dec(a);

In main and the problem is solved. 主要问题解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM