為什麼一些結構中尾部陣列的大小是1?

2021-04-06 17:02:34 字數 1524 閱讀 4497

一些windows結構都是可變大小的,乙個固定大小的頭之後是乙個可變大小的陣列。當這些結構被聲名的時候,陣列大小都宣告為1,舉個例子:

typedef struct _token_groups token_groups, *ptoken_groups;

如果你看這個標頭檔案,你將看到這個anysize_array被定義為1,因此這個結構中宣告了乙個動態擴充套件大小的陣列。

使用這個宣告,你會像下面這個**一樣對乙個可變大小的token_groups結構進行記憶體分配:

ptoken_groups tokengroups =

malloc(field_offset(token_groups, groups[numberofgroups]));

初始化化陣列:

tokengroups->groupcount = numberofgroups;

for (dword index = 0; index = numberofgroups; index++)

很多人認為這個結構應該設計成下面這個樣子:

typedef struct _token_groups token_groups, *ptoken_groups; (

在文中, 以斜體書寫的**都是錯誤的或是假設的)

分配記憶體的**變成了:

ptoken_groups tokengroups =

malloc(sizeof(token_groups) +

numberofgroups * sizeof(sid_and_attributes));

這個方法有兩個缺點,乙個是次要的,而另外乙個是致命的。

首先,次要的缺點是:這種做法非常難以訪問可變大小資料。初始化token_groups**變成:

tokengroups->groupcount = numberofgroups;

for (dword index = 0; index = numberofgroups; index++)

真正的缺點是致命的。上述的**會在64位windows上crash。sid_and_attributes結構如下:

typedef struct _sid_and_attributes sid_and_attributes, * psid_and_attributes;

通過觀察,結構中第乙個成員變數是乙個指標,psid。sid_and_attributes結構需要指標對齊,在64位windows是8位對齊。也就是說,被設想的token_groups  結構是乙個dword,因此只需要4位對齊。sizeof(token_groups)是4。

我相信你已經找到問題的所在了。

在被設想的結構定義中,sid_and_attributes陣列將不是8個位元組對齊,而只是4個位元組對齊。沒有在groupcount 和第乙個sid_and_attributes之間增加padding。在讀取結構中陣列的時候會導致status_datatype_misalignment異常。

也許你會說,為什麼不用0長度的資料來代替1呢?

因為從1999起在c標準中0長度的陣列將不再合法。

為什麼要做一些事

不知不覺間,已經22了,近一兩年經歷了不少事情,年少的輕狂已不復存在,有段時間甚至迷失了方向,不知道自己做的事情意義何在。以前一心想著有朝一日改變自己認為不好的事物,後來慢慢發現自己的力量是多麼渺小,對於太多太多事情,都是滿滿的無力感。於是乎,我在想,那些自身力量那麼弱小的人,是什麼信念支撐他們一直...

為什麼要做一些事

不知不覺間,已經22了,近一兩年經歷了不少事情,年少的輕狂已不復存在,有段時間甚至迷失了方向,不知道自己做的事情意義何在。以前一心想著有朝一日改 變自己認為不好的事物,後來慢慢發現自己的力量是多麼渺小,對於太多太多事情,都是滿滿的無力感。於是乎,我在想,那些自身力量那麼弱小的人,是什麼信念 支撐他們...

一些公司為什麼招不到人

有在 前端人才庫 提了這麼個問題 前端為什麼這麼難招啊?其實答案挺簡單 1.公司小 2.工資少 悲催的是,兩條他還都佔了。任何事情,先在自身找原因。不改變管理層的觀念,招人難永遠是個大問題。人家公司規模在那擺著呢,進去就有乙個光環,google工程師。進去就是乙個大團隊,能學東西。況且重要的是,人家...