我现在了解套接字,我发现它非常令人困惑,因为转换结构。
指南说在 sockaddr_in 中包含 8 位以将其与 sockaddr 进行比较。
所以我的问题是为什么要这样做,我的意思是当你进行转换时,你不会将字符大小与 int 进行比较
例如你这样做
char a[1]='1';
int b=(int)a;
而不是
char a[2]='1';//compare to size of int
int b=(int)a;
那么它是如何工作的呢?
铸件结构有什么不同吗? 如果是的话为什么?
最佳答案
将指针传递给结构时,接收它的函数可能会尝试访问其所有字段中的任何一个。
如果您收到一个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
是打包
- 请参阅 this 了解为什么打包,但这是理想情况)。
因此,假设我们想创建另一个与此兼容的struct
。如果我们创建类似的东西:
struct __attribute__ ((__packed__)) small_pair {
long int first;
char second;
int third;
char forth;
};
我们可以通过强制转换将 structsmall_pair *
传递给任何需要 structpair*
的函数:
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
)。因此,这将是 structsmall_pair
的字段 first
的第三个字节,无论它具有哪个值。
但是,a_pair->last
又如何呢?它是结构体开始后的 0xf
(15) 个字节,但显然超出了它的空间(sizeof(structsmall_pair)
只是 14)。
所以这取决于变量加载到内存中的方式,但显然我们不会引用我们想要的值。最好的情况是当该地址超出我们的进程空间时,我们会收到段错误,并且程序中止。但很可能在内存的该位置声明了另一个变量,并且我们将读取/写入与我们想要的不同的变量,留下谁知道什么结果。
因此,如果我们只是在 structsmall_pair
的末尾添加另一个 2 字节长的字段,我们保证 structpair
的每个可能的引用仍然会存在。在我们自己的struct
中是正确的,因此它们将在内存级别兼容。
然后,它仍然保留了语义级别的兼容性,但这是一个不同的故事:)
关于C语言类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13546564/