我具有這樣的結構,如下保持指針的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個成員,並且類型不能全部重用。但是,是的,我明白了你的想法,並會檢查這是否解決了我的問題。 –