【问题标题】:Storing a Dynamic Array of Structures存储结构的动态数组
【发布时间】:2015-01-31 21:39:43
【问题描述】:

我一直在从事一个利用动态结构数组的项目。为了避免将结构的数量存储在它自己的变量中(结构的数量),我一直在使用一个指向带有NULL 终止符的结构变量的指针数组。

例如,假设我的结构类型定义为:

typedef struct structure_item{
    /* ... Structure Variables Here ... */
} item_t;

现在假设我的代码有 item_t **allItems = { item_1, item_2, item_3, ..., item_n, NULL }; 并且所有 item_#s 都是 item_t * 类型。

使用此设置,我不必跟踪另一个变量,它告诉我项目总数。相反,我可以根据需要确定项目的总数:

int numberOfStructures;
for( numberOfStructures = 0;
     *(allItems + numberOfStructures) != NULL;
     numberOfStructures++
  );

这段代码执行时,会统计NULL之前的指针总数。

作为比较,这个系统类似于 C 风格的字符串;而跟踪结构的总数将类似于 Pascal 样式的字符串。 (因为 C 使用 NULL 终止的字符数组,而 Pascal 则跟踪其字符数组的长度。)

我的问题很简单,指针数组(指向结构的指针)真的有必要吗?或者这可以用结构数组(指向结构的指针)来完成吗?谁能提供更好的方法来处理这个问题?

注意:解决方案与 C C++ 兼容很重要。这被用于包装 C++ 库以用于标准 C 的包装库中。

提前谢谢大家!

【问题讨论】:

  • 除非您有一种简单的方法来检测最后一个 NULL 类型结构,否则通过指针间接使用是理想的。此外,使用指针,您可以在不移动大型结构的情况下进行重组,并在不进行大型重新分配的情况下进行扩展。然而,与 NULL 结束解决方案一样巧妙,遍历整个数组以确定长度可能成为一项昂贵的操作,长度变量或结束指针可以减轻这种情况。
  • 一个简单的问题:如果您存储的某个指针恰好设置为 NULL,那么存储在该指针之后的所有内容会发生什么情况?您很可能会丢失指针和指向的内存,从而导致内存泄漏。所以我想你必须确保这永远不会发生。
  • @SirDarius,这是我想到的,我希望有人能提出一个可以处理这种情况的解决方案。也就是说,存储结构的数量会带来同样的风险,因为 int numberOfStructures 很容易被错误分配到某个地方。
  • 这就是为什么我相信将所有结构直接放在一起,只使用 malloc 分配一次,并且使用 realloc 增长的数组更容易管理,因为当必须释放数组时,所有元素都会被释放在一次操作中,而不必迭代。此外,由于局部性原则,您可能会通过这种方法获得更好的整体性能。
  • @SirDarius,说得好。这绝对是值得考虑的事情。

标签: c++ c arrays pointers struct


【解决方案1】:

您需要的是一个标记值,一个可识别的有效值,意思是“无”。对于指针,标准的标记值是NULL

如果你想直接使用你的结构,你需要确定一个item_t 类型的标记值,并检查它。您的来电。

【讨论】:

  • 这就是我害怕的。我想我会坚持使用指针数组,因为我的代码已经用这种方式编写了,而且我的实际结构有一些开销。感谢您的意见。
【解决方案2】:

是的,可以有一个结构数组,并且(至少)其中一个是已定义的哨兵(即字符串末尾使用的 '\0',在您的情况下为 NULL 指针) .

对于您的结构类型,您需要做的是保留该结构的一个或多个可能值(由其成员的一组值组成)以指示哨兵。

例如,假设我们有一个结构类型

struct X {int a; char *p};

然后定义一个函数

int is_sentinel(struct X x)
{
    return x.p == NULL;
}

这意味着任何成员 p 为 NULL 的结构 X 都可以用作哨兵(在这种情况下成员 a 无关紧要)。

然后循环寻找哨兵。

注意:要在 C 和 C++ 中兼容,结构类型需要兼容(例如 POD)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2020-04-18
    • 1970-01-01
    相关资源
    最近更新 更多