为结构数组中的结构成员分配内存后写入无效

Invalid write after allocating memory for struct member in array of structs

我需要将结构数组传递给函数,据我了解,我必须为整个结构数组以及数组内每个结构中的每个单独结构成员分配内存。

我这样做的方式导致了 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:我知道我必须释放分配的内存,但首先我想让上面的代码工作。

main 中的 test 数组已经为其分配了内存。

然后将它传递给read_file函数,这样就不需要再为它分配内存了。删除这个:

test = (Test *)calloc(16, sizeof(test));

顺便说一句,您可能打算在那里 sizeof(Test)(或者 sizeof(*test))。 sizeof(test)sizeof(Test*) 相同,几乎肯定小于 sizeof(Test)

Test *test

read_file 函数中的 test 变量是测试结构的 pointer

sizeof(test)

这等于指针的大小

test = (Test *)calloc(16, sizeof(test));

这为 16 pointerTest 结构分配了内存。这不会为 16 个结构分配内存,只为指向它们的指针分配内存。

test[0].string1 = 

无效并发生未定义的行为。由于 sizeof(test)sizeof(Test) 小得多,因此没有足够的内存来访问 test0[].string1。所以这会访问内存 "out of bounds" 并且会访问无效/未分配的内存区域。当您尝试写入它(您正在做一个分配)时,表达式无效并且发生未定义的行为。 Valgrind 正确地将其检测为 "write error" - 您尝试写入不属于您的内存。