传递指向结构的指针时,接收它的函数可能会尝试访问其所有字段中的任何一个。
如果您收到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