gpt4 book ai didi

c - 基于两种可能结构的未知空指针的访问类型标志?

转载 作者:太空狗 更新时间:2023-10-29 17:21:06 28 4
gpt4 key购买 nike

我目前正在用 C 编写自己的八叉树。该树将包含数十亿个对象,因此内存效率是关键。为实现这一点,我目前使用一个带有标志和 union 的结构,但我认为它不干净并且浪费内部节点的空间,因为我只需要一个 8 位标志,但为 64 位保留了内存指数。我目前的代码如下:

typedef struct _OctreeNode
{
uint64_t location_code;
union
{
uint8_t child_exists;
uint64_t object_index;
} data;
uint8_t type;
} OctreeNode;

我想把它分成两个不同的结构。一个叶子节点和一个内部节点。如下:

typedef struct _OctreeInnerNode
{
uint64_t location_code;
uint8_t child_exists;
uint8_t type;
} OctreeInnerNode;

typedef struct _OctreeLeafNode
{
uint64_t location_code;
uint64_t object_index;
uint8_t type;
} OctreeLeafNode;

现在问题出现在我基于位置代码散列的无序 map 上。它使用 void 指针,因此存储两个不同的结构不是问题。我知道有一种可能性是让标志成为第一个元素并取消引用指向标志数据类型的指针来派生类型,如下所示:

typedef struct _OctreeLeafNode
{
uint8_t type;
uint64_t location_code;
uint64_t object_index;
} OctreeLeafNode;

void
func(void* node)
{
uint8_t type = *(uint8_t*)node;
if (type == LEAF_NODE) {
OctreeLeafNode* leaf_node = (OctreeLeafNode*)node;
}
}

我想知道是否有更清洁的方法。还是不推荐这样做?我应该如何处理结构和 void 指针的多种可能性?

提前致谢!

最佳答案

这是C中常用的方法。

但只需将这些字段放在结构的开始(第一个字段)并且永远不要改变它们的位置。此外,您需要将它们保留在所有结构中。

此方法的一个常见示例是结构中的 version 字段(或在您的情况下为 type)。您可以将它们保留在结构的开头,然后通过类似的方法检查结构版本。像这样:

struct _base {
uint8_t ver;
};

#define TYPE_OLD 0
struct _a_old {
struct _base info;
uint8_t a;
};

#define TYPE_NEW 1
struct _a_new {
struct _base info;
uint8_t a;
uint8_t b;
};

现在您可以通过将数据转换为 struct _base 并检查 ver 字段来识别不同的类型。

unsigned char* buf = ...
switch (((struct _base*)buf)->ver)
{
case TYPE_OLD:
{
struct _a_old* old = (struct _a_old*)buf;
// ...
break;
}
case TYPE_NEW:
{
struct _a_new* old = (struct _a_new*)buf;
// ...
break;
}
default:
// ...
}

关于c - 基于两种可能结构的未知空指针的访问类型标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53304811/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com