【问题标题】:Allocation of variables inside dynamically allocated structs在动态分配的结构中分配变量
【发布时间】:2018-12-29 19:49:33
【问题描述】:

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

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));)时会发生什么,为什么我应该选择一种方式而不是另一种方式?

【问题讨论】:

  • “它可以通过两种方式完成”——这两个不同的结构非常非常不同。
  • 始终努力使用更少的指针。如果你能解释为什么你绝对需要一个指针,那就太好了。如果你不能,你就不需要它。因此,除非您出于某种特定原因需要 Base2,否则 Base1 可以防御。
  • @n.m.如果array 具有已知大小,则该数组也可以就地存在:int array[1234] 完全避免动态分配(或指向堆栈分配的数组)。

标签: c struct dynamic-allocation


【解决方案1】:
  1. 嵌套结构的空间作为其父结构中的空间存在,这意味着它们不需要自己的分配(但它们可能仍需要自己的初始化),而作为指针的结构字段都需要分配并在父对象启动时释放(这是 C 中内存泄漏的常见原因,因为它没有像 C++ 那样的自动对象析构函数)。虽然如果使用指针,您可以指向堆栈中可能存在的另一个数组/对象(从而避免malloc/free),但是您可能会遇到对象生命周期错误,具体取决于对象的范围和生命周期的差异.

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

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

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

【讨论】:

    【解决方案2】:

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

    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);
    

    【讨论】:

    • 由于 C 没有访问修饰符,它提出了谁“拥有”内部指向对象以及谁负责在这些内部对象上调用 free 的问题。对于按值成员,它是自动的。
    猜你喜欢
    • 2021-07-06
    • 1970-01-01
    • 2015-07-23
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多