在动态分配的结构中分配变量

Allocation of variables inside dynamically allocated structs

假设有一个包含指向数组及其大小的指针的结构,如下所示:

typedef struct {
    int * array;
    int arr_size;
}IntArray;

并想将它放在另一个结构中,可以通过两种方式完成:

typedef struct{
    IntArray ia;
    //other variables
}Base1;

typedef struct{
    IntArray * ia;
    //other variables
}Base2;

当我动态分配 Base1Base2(例如 Base1 b1 = (Base1 *)malloc(sizeof(Base1));)时会发生什么,为什么我应该选择一种方式而不是另一种方式?

基本上问题是一样的,我应该分配一个结构还是一个指向结构的指针?即:

IntArray myStruct;

IntArray *myStructPtr;

所讨论的变量在结构中这一事实没有区别,您可以选择其中一个。

当然,在引用外部结构内部的字段之后,您访问它们的方式与它们不在另一个结构内部时的访问方式相同,所以

Base1 包含实际的 IntArray 结构,因此您会

Base1 *b1 = malloc(sizeof(*b1));
b1->ia.array = malloc(yourSizeHere);

Base2 包含指向 IntArray 结构的指针,因此您需要将其指向现有的 IntArray 结构或 malloc() 内存,然后访问它作为指针。

Base2 *b2 = malloc(sizeof(*b2));
b2->ia = malloc(sizeof(*(b2->ia)));
b2->ia->array = malloc(yourSizeHere);
  1. 嵌套结构的 space 在其父结构中作为 space 存在,这意味着它们不需要自己的分配(但它们可能仍需要自己的初始化) ,而作为指针的结构字段需要在父对象启动时分配和释放(这是 C 中内存泄漏的常见原因,因为它没有像 C++ 那样的自动对象析构函数)。尽管如果使用指针,您可以指向堆栈中可能存在的另一个 array/object(从而避免 malloc/free),但您可能 运行 进入对象生命周期错误,具体取决于关于对象范围和生命周期的差异。

  2. 嵌套结构就地存在,因此它们不能被其他实例共享。这可能是理想的,也可能不是理想的(你可以用 C++ 中的模板解决这个问题,在 C 中你必须满足于 a hideous preprocessor macro)。

  3. 因为动态分配的对象(例如您的数组 您的 Base2 类型的嵌套 ia 成员)存在于不同的位置在物理内存中,这意味着您的代码将不会利用 CPU 的缓存可以利用 的空间局部性,您将导致双指针取消引用。所以你的代码会 运行 变慢。

无论如何:在 C 中,您通常应该尽量减少指针的使用。