char* 上的 free() 被 valgrind 识别为无效

sme*_*oks 1 c malloc free valgrind pointers

我试图释放 char** 数组中存在的 char* 指针,但 valgrind 确定此操作无效。

这是我正在做的一个简单示例:

struct building{
  int propertyPrice;
  int totalArea;
  char** floors;
}

int main(){

  struct building* B = malloc(sizeof(struct building));

  for(size_t i=0;i<10;i++)
    B->floors[i] = malloc(20 * sizeof(char*));

}

Run Code Online (Sandbox Code Playgroud)

这就是我感到困惑的地方 - 我可以通过以下循环访问元素:

for(size_t i=0;i<10;i++)
    printf("%s", B->floors[i]); //assume that a valid string exists at each floors[i]!

Run Code Online (Sandbox Code Playgroud)

尝试按如下方式释放分配的内存:

for(size_t i=0;i<10;i++)
    free(B->floors[i]);

free(B);
Run Code Online (Sandbox Code Playgroud)

请原谅缺少对 NULL 的 malloc() 检查,为了简洁起见,我将其删除。

Valgrind 确定该操作free(B->floors[i])Invalid free() / delete / delete[] / realloc()。然而,如果我可以通过 访问各个 char* 元素B-floors[i],我是否应该能够使用相同的语法通过将函数调用从 切换printf()到 来释放它(我从这个 stackoverflow 答案free()中得到了这个想法)?

第二个free()电话工作得很好。

我的程序按预期执行,但我想摆脱内存泄漏 - 因此使用 valgrind。如果有帮助的话,我在执行 valgrind 时使用-Werror -ggdbgcc 的开关和--track-origins=yes --leak-check=full参数。

Dav*_*eri 5

这里:

for(size_t i=0;i<10;i++)
    B->floors[i] = malloc(20 * sizeof(char*));
Run Code Online (Sandbox Code Playgroud)

B->floors未初始化时使用。

您需要为 10 个元素预留空间:

B->floors = malloc(10 * sizeof(char*));
Run Code Online (Sandbox Code Playgroud)

然后你可以填充锯齿状数组:

for (int i = 0; i < 10; i++) {
    B->floors[i] = strdup(...); // or malloc + memcpy if strdup is not available
}
Run Code Online (Sandbox Code Playgroud)

最后:

for (int i = 0; i < 10; i++) {
    free(B->floors[i]);
}
free(B->floors);
Run Code Online (Sandbox Code Playgroud)

由于floors是数组的最后一个成员,因此您可以将其用作“灵活数组成员”:

struct building* B = malloc(sizeof(struct building) + (sizeof(char *) * 10));
Run Code Online (Sandbox Code Playgroud)

free(B->floors);在这种情况下,您最后不会调用。