傳遞指向結構的指針時,接收它的函數可能會嘗試訪問其所有字段中的任何一個。
如果您收到struct something *
,您希望您可以讀取接收到的指針後面的任何sizeof(struct something)
字節。所以,不保留這些字節在你自己的struct
會使它們不兼容 - 只要函數試圖訪問你沒有分配的字節,它就會訪問非保留的內存,所以它可能是一個分段錯誤,或者可能會破壞另一個的結構數據。
看看這個程序:
#include <stdlib.h>
#include <stdio.h>
struct __attribute__ ((__packed__)) pair {
short first;
char second;
long int third;
int forth;
char last;
};
void main(void) {
struct pair myPair;
printf("myPair is at 0x%x\n", &myPair);
printf("myPair.first is at 0x%x\n", &(myPair.first));
printf("myPair.second is at 0x%x\n", &(myPair.second));
printf("myPair.third is at 0x%x\n", &(myPair.third));
printf("myPair.forth is at 0x%x\n", &(myPair.forth));
printf("myPair.last is at 0x%x\n", &(myPair.last));
}
和一個樣本輸出:
myPair is at 0xabbd0aa0
myPair.first is at 0xabbd0aa0
myPair.second is at 0xabbd0aa2
myPair.third is at 0xabbd0aa3
myPair.forth is at 0xabbd0aab
myPair.last is at 0xabbd0aaf
我們在這裏學到的是,每個字段下一個存儲的前一個內存,更準確地說是sizeof(previous_field)
個字節到前一個字段的右側(當struct
是packed
- 請參閱this瞭解爲什麼包裝,但是th是理想的情況)。
所以,想象一下,我們想創建另一個struct
與此兼容。如果我們創建類似:
struct __attribute__ ((__packed__)) small_pair {
long int first;
char second;
int third;
char forth;
};
我們可以通過一個struct small_pair *
給需要一個struct pair *
由鑄造任何功能:
void my_function(struct pair *);
void main(void) {
struct small_pair my_small_pair;
// ...
my_function((struct pair*) &my_small_pair);
// ...
}
void my_function(struct pair *a_pair) {
//...
printf("Second character of pair is %c\n", a_pair->second);
//...
printf("Last character of pair is %c\n", a_pair->last);
//...
}
一旦編譯,訪問a_pair->second
是「讀一個字節是兩個字節「結構開始之後」(0xabbd0aa2 - 0xabbd0aa0 = 2
)。所以這將是struct small_pair
的字段first
的第三個字節,無論它有哪個值。
但是,a_pair->last
呢?在結構開始之後它是0xf
(15)個字節,但它明顯超出了它的空間(sizeof(struct small_pair)
僅爲14)。
所以它將取決於變量加載到內存中的方式,但顯然我們不會指向我們想要的值。最好的情況是,當這個地址超出我們的進程空間時,所以我們得到一個分段錯誤,程序中止。但很可能存在另一個在內存中聲明的變量,我們將從我們想要的內容讀取/寫入一個不同的變量,留下誰知道什麼結果。
所以,如果我們只是再添2字節長的字段添加到struct small_pair
年底,我們保證一個struct pair
的每一個可能的基準仍是正確的在我們自己struct
,所以他們會在內存兼容-水平。
然後,它仍然留在語義級別的兼容性,但是這是一個不同的故事:)
'char a [2] ='1''不會編譯也不會'char a [1] ='1'' –
爲什麼它不會編譯? – user1801625
你不能施放'struct's,所以我不知道這是關於什麼的。 – melpomene