【问题标题】:How to construct and manage this complex C data structure?如何构建和管理这个复杂的 C 数据结构?
【发布时间】:2011-10-26 10:05:48
【问题描述】:

我很困惑如何在 C 中有效地管理(填充和访问)以下数据结构。简而言之,我有一个包含另一个结构成员的结构,并且该结构具有另一个不同的成员结构等等。像这样的:

typedef struct
{
    int num;
} D;

typedef struct
{
    D *boo;
} C;

typedef struct
{
    C *far;
} B;

typedef struct
{
    int foo;
    B *bar;
} A;

A *func() {
    A *var;
    // POPULATE var
}

int main(...) {
    A *a = func();
    // PRINTING
}

那么,哪种方式是管理这种数据结构的最佳方式?我的意思是我将如何填充这个 A 类型指针的数据?

假设我要打印a 保留的所有数据(// PRINTING),我想我会得到类似:a->bar->far->boo->num。我不知道这是否正常工作,因此是否可靠。

【问题讨论】:

  • 您可能想要做的第一件事是将每个单个成员 struct 替换为 typedef

标签: c data-structures struct


【解决方案1】:

这不会更容易,例如Python,如果你选择这样一个分散的设计,那么管理起来自然会有点痛苦。

打印就像你说的那样工作,C 的-> 运算符通常就是这样使用的。当然,如果可能存在结构不“完整”的 NULL 指针,则需要在取消引用指针之前对其进行检查,否则您将出现未定义的行为。

填充可能最好通过编写函数在每一层创建一个实例来完成,然后可以在链中相互调用以设置最顶层的类型:

D* d_create(int num);
C* c_create(int num);
B* b_create(int num);

A* a_create(int foo, int num)
{
   A* a = malloc(sizeof *a);
   if(a != NULL)
   {
     a->foo = foo;
     a->bar = b_create(num);
     if(a->bar != NULL)
       return a;
     free(a);
   }
   return NULL;
}

这有点麻烦,因为所有实际数据(foonum)都必须传递给创建 A 实例的顶级函数,但它可以工作并且非常简单.

请注意我们如何通过确保B 指针不是NULL 来从较低级别的内存分配器中捕获错误。在其他create-functions 中也需要这些类型的检查。

【讨论】:

  • +1 以获得如此好的答案,我会考虑更多并尽快回复您。
  • unwind,只是一个简单的问题:归还后如何释放(a)?程序还会执行 free() 函数吗?
【解决方案2】:

在不知道您为什么选择使用指针的情况下,无法回答“我该如何管理”。如果每个A都有自己的B等等,那么你需要在分配A时分配​​B,在释放A时释放它。但在这种情况下,指针是无用的,并且会产生额外的工作。你本来可以这样做的:

typedef struct
{
    int num;
} D;

typedef struct
{
    D boo;
} C;

typedef struct
{
    C far;
} B;

typedef struct
{
    int foo;
    B bar;
} A;

A func() { // don't necessarily need to return a pointer here either
    A var;
    var.foo = 1;
    var.bar.far.boo.num = 2;
    return var;
}

如果指针的原因是您可能有多个A 实例都指向B 的同一个实例,那么您需要决定如何知道B 的实例何时不存在使用时间更长,可以释放。有一些通用解决方案,例如引用计数,或者可能有一些特定于您的应用程序的东西可以让问题的答案变得简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多