假设具有一个包含指向数组及其大小的指针的结构,如下所示:
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));
)时会发生什么,为什么我应该选择一种方式而不是另一种方式?
答案 0 :(得分:3)
嵌套结构的空间作为其父结构中的空间存在,这意味着它们不需要自己的分配(但它们可能仍需要自己的初始化),而作为指针的结构字段则需要同时分配并在父对象启动时释放(这是C中内存泄漏的常见原因,因为它不像C ++那样具有自动对象析构函数)。虽然如果使用指针可以指向堆栈上可能存在的另一个数组/对象(因此避免使用malloc
/ free
),但是根据作用域和范围的不同,您可能会遇到对象生存期错误。对象的生命周期。
嵌套结构就位存在,因此其他实例无法共享它们。这可能是理想的,也可能不是理想的(您可以使用C ++中的模板解决此问题,在C中,您必须满足a hideous preprocessor macro的要求。)
由于动态分配的对象(例如数组和您的Base2
类型的嵌套ia
成员)存在于物理内存中的不同位置,因此这意味着您的代码不会利用CPU的缓存可以利用 的空间局部性,您将招致双指针取消引用。因此,您的代码运行速度会变慢。
无论如何:在C语言中,通常应尽量减少指针的使用。
答案 1 :(得分:1)
基本上,问题与我应该分配结构还是指向结构的指针相同?那就是:
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);