我具有这样的结构,如下保持指针的C中的阵列指向两个相关类型
struct things
{
BOOL_T is_copy; /* is false */
handle1 h1;
handle2 h2;
int n;
void * memory;
};
有时我使things
对象的拷贝在下面结构
struct copy_of_things
{
BOOL_T is_copy; /* is true */
handle1 h1; /* I don't need h2 and n here */
void * memory; /* copied from things object and
things object allocates new memory */
int another_member;
};
此外,我在管理器中有一个结构阵列,可以让所有的things
和copy_of_things
结构保持在我的程序中(称为struct things *things_array[SIZE_OF_ARRAY];
)。由于设计要求,我无法管理2个数组(阵列与散列相似)。为了实现这一目标,我做了这个数组的类型,thing *
和改变的copy_of_things
类型如下
struct copy_of_things
{
struct things ths;
int another_member;
};
现在我可以阅读我的数组元素的is_copy
成员,并决定是否将其解释为things
或copy_of_things
。
我觉得这不仅是inefficient
在内存方面,但ugly
看。
解决方案2 我也打算使用的数组类型是struct of type(is_copy) and a union
。
struct things {
BOOL_T is_copy;
union {
struct { /* is_copy = false */
handle1 h1;
handle2 h2;
int n;
void * memory;
} t;
struct { /* is_copy = true */
handle1 h1;
void * memory;
int another_member;
} c;
};
但是,虽然审查我发现这种设计也很丑。
解决方案3我打算保留BOOL_T is_copy;
作为两种结构的第一个成员,并保留BOOL_T
类型的数组。在阅读BOOL_T
的内容后,我可以取消引用我的指针或copy_of_things。我不确定这是否是一个好的解决方案,并提供了一个定义良好的行为(在更高级别的优化中),因为相同的地址被解释为不同的类型。
问题 是否有更好的解决方案可以解决我的问题,在任何平台上都是可移植的。
编辑
谢谢你的答案。所以有两个建议的选择。
- 使用联盟:该方法的缺点是,它需要更多的副本内存。在我的情况下,
sizeof copy_of_things
明显小于sizeof things
。一种解决方法是分配恰好足够的字节,其中实际的对象可以驻留。 - 使用一个公用的结构体并使其成为
copy_of_things
和things
的第一个成员。在这里,我最终会用两种类型(struct common和struct things或struct copy_of_things)去引用相同的内存位置。我不知道strict aliasing rule不会咬我。 - 还有一种解决方案可以将两个结构的第一个成员保存为
char is_copy; /* \0 if not a copy, non zero otherwise
,并仅访问指针char *
或things *
或copy_of_things *
。
仍然悬而未决的问题
我见过的解决方案2中使用的许多地方。是否严格别名规则安全?由于代码将在各种编译器上编译,是否有更好的解决方案?反向映射数组的大小很大,所以我避免使用联合或增加反向映射大小的解决方案。事物(和副本)的数量较少,所以可以在那里添加新的数据成员。
你能不能让两个结构都是同一个类型?而在“copy”语义中,'h2'没有被使用,'n'被重用? –
@MattMcNabb谢谢。实际结构包含大约12个成员,并且类型不能全部重用。但是,是的,我明白了你的想法,并会检查这是否解决了我的问题。 –