一些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工程師。進去就是乙個大團隊,能學東西。況且重要的是,人家...