gpt4 book ai didi

c - Valgrind 无效写入大小 8

转载 作者:太空宇宙 更新时间:2023-11-04 05:36:11 25 4
gpt4 key购买 nike

我有一些代码可以分解如下例所示的字符串并将其存储到数据结构中。

ORGANIZER;CN=John Doe;ON=Another Person;SN=Maybe another

这是我的函数的样子:

CalError parseOptionalParam(char * paramString, CalParam * param) {
char * parseString = malloc(strlen(paramString) + sizeof(char*));
strcpy(parseString, paramString);

char * tokenSemi;
tokenSemi = strtok(parseString, ";");
if(tokenSemi == NULL) return SYNTAX;
int i = 0;
while(tokenSemi != NULL) {
tokenSemi = strtok(NULL, ";");
if(tokenSemi == NULL) return SYNTAX;

char * tokenEqual = strtok(tokenSemi, "=");
param->name = malloc(strlen(tokenEqual) + sizeof(char*));
strcpy(param->name, tokenEqual);

param = realloc(param, sizeof(param) + sizeof(char*));
tokenEqual = strtok(tokenSemi, "=");
param->value[i] = malloc(sizeof(char*) + strlen(tokenEqual));
strcpy(param->value[i], tokenEqual);

i++;
}
free(parseString);
return OK;
}

这是 valgrind 告诉我的:

==7925== Invalid write of size 8
==7925== at 0x400E56: parseOptionalParam (calutil.c:79)
==7925== by 0x400CED: parseCalProp (calutil.c:50)
==7925== by 0x400B0B: main (testfile.c:8)
==7925== Address 0x5202508 is 8 bytes after a block of size 16 alloc'd
==7925== at 0x4C2DD9F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7925== by 0x400E13: parseOptionalParam (calutil.c:77)
==7925== by 0x400CED: parseCalProp (calutil.c:50)
==7925== by 0x400B0B: main (testfile.c:8)

第 79 行是以 param->value[i] = 开头的行,然后 valgrind 指的是上面 2 行的 realloc。我很困惑这里出了什么问题?在 param 结构中,结构末尾有一个灵活的数组成员,即 value。我只是想在结构中分配另一个数组位置,然后将该位置用于字符串。

在这两行中的某个时刻,我猜我在内存方面做了一些不正确的事情,但我不确定它是什么。

最佳答案

Within the param structure there is a flexible array member at the end of the structure which is value. I am simply trying to allocate another array position in the structure and then use that position for a string.

让我们计算一下:为了给 CalParam 分配足够的空间,其灵活的数组成员具有您需要的 i 元素

  • sizeof(CalParam) - 这是您的struct
  • 的基本大小
  • (i+1)*sizeof(char*) - 这是一个 char* 数组,大小为 i+1

因此,您的 realloc 调用应该如下所示:

param = realloc(param, sizeof(*param) + (i+1)*sizeof(char*));

注意 param 前面的星号。这很重要,因为 param 是一个指针。

然而,故事还没有结束,因为 param 是按值传递的,而您正在通过 realloc 更改它的值。这将导致调用者中出现悬空引用。为了解决这个问题,您需要逐个指针(即双星号指针)接收 param 指针,并在调用 realloc 时分配它,如下所示:

CalError parseOptionalParam(char * paramString, CalParam **param) {
...
*param = realloc(*param, sizeof(**param) + (i+1)*sizeof(char*));
...
}

请注意此处的更多星号。为了使您的代码更易于阅读,请考虑将第一个 sizeof 替换为 sizeof(CalParam),如下所示:

*param = realloc(*param, sizeof(CalParam) + (i+1)*sizeof(char*));

最后,您还应该使用 realloc 修复潜在的内存泄漏:不是直接分配给 *param,您应该分配给一个临时的,检查 NULL,然后分配回 *param,或者释放旧值并报告错误。

关于c - Valgrind 无效写入大小 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35023446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com