這部分取決於元素類型。你一定可以用字符串來做到這一點;與其他一些類型一樣,你不得不擔心對齊和填充問題。
struct data_channel
{
char *chan_name;
char *chan_type;
char *chan_units;
};
struct data_channel *chan;
size_t name_size = 9;
size_t type_size = 10;
size_t unit_size = 5;
chan = malloc(sizeof(struct data_channel) + name_size + type_size + unit_size);
if (chan != 0)
{
chan->chan_name = (char *)chan + sizeof(*chan);
chan->chan_type = chan->chan_name + name_size;
chan->chan_units = chan->chan_type + type_size;
}
這將在實踐中運行良好 - 在標準標準化之前它已經過了很長時間。我不能立即明白爲什麼標準會禁止這一點。
更棘手的是,如果你需要分配一個數組int
,以及兩個字符串。那麼你不得不擔心對齊問題。
struct data_info
{
char *info_name;
int *info_freq;
char *info_unit;
};
size_t name_size = 9;
size_t freq_size = 10;
size_t unit_size = 5;
size_t nbytes = sizeof(struct data_info) + name_size + freq_size * sizeof(int) + unit_size;
struct data_info *info = malloc(nbytes);
if (info != 0)
{
info->info_freq = (int *)((char *)info + sizeof(*info));
info->info_name = (char *)info->info_freq + freq_size * sizeof(int);
info->info_unit = info->info_name + name_size;
}
這已通過分配最嚴格對齊類型(int
陣列),然後再後來分配串的簡單的權宜之計。然而,這部分是你必須對可移植性作出判斷的地方。我相信代碼在實踐中是可移植的。
C11具有定位設備(_Alignof
和_Alignas
和<stdalign.h>
,加上max_align_t
在<stddef.h>
),可以改變這個答案(但我沒有研究過足夠的,所以我不知道如何,還),但在這裏列出的技術將在任何版本的C中工作,只要您注意數據的對齊。請注意,如果在結構中有單個陣列,那麼C99提供了一種替代舊的'struct hack'(稱爲)的靈活陣列成員(FAM)。這使您可以顯式地將數組作爲結構的最後一個元素。
struct data_info
{
char *info_name;
char *info_units;
int info_freq[];
};
size_t name_size = 9;
size_t freq_size = 10;
size_t unit_size = 5;
size_t nbytes = sizeof(struct data_info) + name_size + freq_size * sizeof(int) + unit_size;
struct data_info *info = malloc(nbytes);
if (info != 0)
{
info->info_name = ((char *)info + sizeof(*info) + freq_size * sizeof(int));
info->info_units = info->info_name + name_size;
}
請注意,本例中沒有初始化FAM的步驟,info_freq
。你不能有這樣的多個數組。
請注意,概述的技術不容易應用於結構數組(至少,外部結構數組)。如果你付出相當大的努力,你可以讓它工作。另外,請注意realloc()
;如果您重新分配空間,則必須在數據移動時修復指針。
另一點:特別是在64位機器上,如果字符串的大小足夠統一,那麼你可能會更好地在結構中分配數組,而不是使用指針。
struct data_channel
{
char chan_name[16];
char chan_type[16];
char chan_units[8];
};
這佔用40個字節。在一個64位的機器上,原始數據結構將佔據三個指針的24個字節和(9 + 10 + 5)個字節的數據的另外24個字節,總共分配了48個字節。
有一個明顯的錯誤,那會導致代碼不能編譯。 –
@JoachimPileborg - 你的意思是陳不是一個數組? –
看起來非常危險且不便攜。我只是建立一個分配例程(用於結構)和一個釋放例程(用於結構)並完成它。無論如何你必須分配和釋放它,所以只需封裝你不想處理的額外指針即可。 – Jiminion