我需要将一个结构数组传递给一个函数,我的理解是我必须为整个结构数组以及数组中每个结构中的每个结构成员分配内存。
我这样做的方式导致valgrind的写入错误(在函数read_file中的第二行引起)。怎么了?
typedef struct test
{
char *string1;
int num1;
int num2;
char *string2;
} Test;
static void read_file(Test *test)
{
test = (Test *)calloc(16, sizeof(test));
test[0].string1 = (char *)calloc(strlen("hello") + 1, sizeof(char));
}
int main(void)
{
int i = 0;
Test test[16];
for (i = 0; i < 16; i++)
{
memset(&test[i], 0, sizeof(test[i]));
test[i] = (Test) { "", 0, 0, "" };
}
read_file(test);
return 0;
}
PS:我知道我必须释放分配的内存,但首先我想让上面的代码工作。
Test *test
test
函数中的read_file
变量是Test结构的pointer
。
sizeof(test)
这等于指针的sizeof。
test = (Test *)calloc(16, sizeof(test));
这为指向Test
结构的16指针分配内存。这不会为16个结构分配内存,仅用于指向它们的指针。
test[0].string1 =
无效且未定义的行为发生。由于sizeof(test)
比sizeof(Test)
小,因此没有足够的记忆来访问test0[].string1
。因此,它访问内存“越界”,这将访问无效/未分配的内存区域。当你尝试写它(你正在做一个分配)时,表达是无效的,并且发生了未定义的行为。 Valgrind正确地检测到“写入错误” - 您尝试写入您不拥有的内存。
test
中的main
数组已经为它分配了内存。
然后将其传递给read_file
函数,因此您无需再次为其分配内存。删除这个:
test = (Test *)calloc(16, sizeof(test));
顺便说一句,你可能打算在那里使用sizeof(Test)
(或者sizeof(*test)
)。 sizeof(test)
与sizeof(Test*)
相同,几乎肯定比sizeof(Test)
小。