【问题标题】:Why does Valgrind reports an invalid free() after a realloc()?为什么 Valgrind 在 realloc() 之后会报告无效的 free()?
【发布时间】:2012-05-15 12:43:47
【问题描述】:

当我在以下(示例)代码上运行 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;
}

【问题讨论】:

    标签: c free valgrind realloc


    【解决方案1】:

    在您的函数main 中,您将a 按值传递给vl_dec,因此它永远不会被更新-realloc 的结果仅存储在一个局部变量中,当vl_dec 返回时该变量会丢失。相反,传递它的地址:

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

    【讨论】:

      【解决方案2】:

      您不能仅仅假设realloc 返回的a 的新值与旧值相同。您实际上必须在每个使用它的地方更新指针。我怀疑您知道这一点,因为您正确地将realloc 的返回值保存在vl_dec 中,但是您忘记了需要从vl_dec 返回a 的新值(或使用@ 更新它987654327@ 作为vl_dec 的参数。)

      【讨论】:

        【解决方案3】:

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

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

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

           a = vl_dec(a);
        

        在 main 中,问题已解决。

        【讨论】:

          猜你喜欢
          • 2014-08-18
          • 2016-08-17
          • 2013-12-17
          • 1970-01-01
          • 1970-01-01
          • 2020-05-05
          • 1970-01-01
          • 1970-01-01
          • 2023-04-06
          相关资源
          最近更新 更多