在动态分配的结构中分配变量
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;
当我动态分配 Base1
和 Base2
(例如 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);
嵌套结构的 space 在其父结构中作为 space 存在,这意味着它们不需要自己的分配(但它们可能仍需要自己的初始化) ,而作为指针的结构字段需要在父对象启动时分配和释放(这是 C 中内存泄漏的常见原因,因为它没有像 C++ 那样的自动对象析构函数)。尽管如果使用指针,您可以指向堆栈中可能存在的另一个 array/object(从而避免 malloc
/free
),但您可能 运行 进入对象生命周期错误,具体取决于关于对象范围和生命周期的差异。
嵌套结构就地存在,因此它们不能被其他实例共享。这可能是理想的,也可能不是理想的(你可以用 C++ 中的模板解决这个问题,在 C 中你必须满足于 a hideous preprocessor macro)。
因为动态分配的对象(例如您的数组 和 您的 Base2
类型的嵌套 ia
成员)存在于不同的位置在物理内存中,这意味着您的代码将不会利用 CPU 的缓存可以利用 和 的空间局部性,您将导致双指针取消引用。所以你的代码会 运行 变慢。
无论如何:在 C 中,您通常应该尽量减少指针的使用。
假设有一个包含指向数组及其大小的指针的结构,如下所示:
typedef struct {
int * array;
int arr_size;
}IntArray;
并想将它放在另一个结构中,可以通过两种方式完成:
typedef struct{
IntArray ia;
//other variables
}Base1;
typedef struct{
IntArray * ia;
//other variables
}Base2;
当我动态分配 Base1
和 Base2
(例如 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);
嵌套结构的 space 在其父结构中作为 space 存在,这意味着它们不需要自己的分配(但它们可能仍需要自己的初始化) ,而作为指针的结构字段需要在父对象启动时分配和释放(这是 C 中内存泄漏的常见原因,因为它没有像 C++ 那样的自动对象析构函数)。尽管如果使用指针,您可以指向堆栈中可能存在的另一个 array/object(从而避免
malloc
/free
),但您可能 运行 进入对象生命周期错误,具体取决于关于对象范围和生命周期的差异。嵌套结构就地存在,因此它们不能被其他实例共享。这可能是理想的,也可能不是理想的(你可以用 C++ 中的模板解决这个问题,在 C 中你必须满足于 a hideous preprocessor macro)。
因为动态分配的对象(例如您的数组 和 您的
Base2
类型的嵌套ia
成员)存在于不同的位置在物理内存中,这意味着您的代码将不会利用 CPU 的缓存可以利用 和 的空间局部性,您将导致双指针取消引用。所以你的代码会 运行 变慢。
无论如何:在 C 中,您通常应该尽量减少指针的使用。