struct 的初始化函数(即 "constructor"),为什么变量没有正确初始化?

Initialization function (i.e. "constructor") for struct, why are variables not being initialized properly?

我有一个名为“FooStruct”的未命名结构,我为它编写了一个函数来初始化它的所有变量并负责动态内存分配。

我试过 运行 这段代码,但它没有产生我期望的结果。出于某种原因,变量在函数内部正确初始化,但一旦退出块,它们就会再次更改。

我正在从事的一个项目要求我只能使用未命名的结构。为什么会这样?

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int fooPrimitive;
} FooStruct;

void FooStructInit(FooStruct * ptr, int num) {
    ptr = (FooStruct*)malloc(sizeof(FooStruct));
    ptr -> fooPrimitive = num;

    // Expected output: 5
    // Actual output: 5
    printf("ptr -> fooPrimitive: %d\n", (ptr -> fooPrimitive));
}

int main() {
    FooStruct * ptr;
    FooStructInit(ptr, 5);

    // Expected output: 5
    // Actual output: some random number
    printf("FooStruct -> fooPrimitive: %d\n", (ptr -> fooPrimitive));
}

当您将 ptr 传递给 FooStructInit 时,它被 复制 并且此副本被分配 return 值 malloc 然后。这称为 按值传递。相反,将指针传递给 ptr 以实际写入 ptr 而不仅仅是传递的参数:

void FooStructInit(FooStruct** ptr, int num) {
    *ptr = malloc(sizeof(FooStruct));
    (*ptr)->fooPrimitive = num;

    // Expected output: 5
    // Actual output: 5
    printf("(*ptr)->fooPrimitive: %d\n", ((*ptr)->fooPrimitive));
}

int main() {
    FooStruct* ptr;
    FooStructInit(&ptr, 5);

    // Expected output: 5
    // Actual output: 5
    printf("FooStruct->fooPrimitive: %d\n", (ptr->fooPrimitive));
}

备注:

  • malloc
  • 之后调用 free
  • don't cast the result of malloc

C只有按值传递语义,所以当你将指针传递给函数时,指针的原始值不会改变,只会改变函数中的本地副本。

解决这个问题的方法是将指针传递给指针,这样您就可以更改原始内存位置的值。

void FooStructInit(FooStruct **ptr, int num) {
    *ptr = malloc(sizeof(FooStruct));
    ...
}

int main(void) {
    FooStruct * ptr;
    FooStructInit(&ptr, 5); /* get the address of the pointer */
    ...
}