我有以下c程序
struct in_addr {
unsigned long s_addr; // load with inet_aton()
};
struct sockaddr_in {
short a;
unsigned short b;
struct in_addr c;
char d[8];
};
int main(int argc, char** argv) {
struct sockaddr_in *record1;
record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in*));
memset(record1, 0, 14);
record1->a = 16;
record1->b = 4;
//strcpy(record1->sin_zero, "1");
printf("Struct record1: %x", *record1);
}
当我单独指定 record1-> a = 16 时,我得到“结构记录1:10 ”
当我指定 record1-> a = 16 和 record1-> b = 4 时,我得到“结构记录1:40010 “(我可以发现它是Little Endianness,但仍然 *我的预期输出 04 10 * (短片各占两个字节))
当我指定 record1-> a = 16; * record1-> b = 4; * record1-> c.s_addr = 1UL ; * strcpy(record1-> d,“1”); * 输出仍然是“结构记录1:40010 ”( Y是对long的赋值而char []未反映?)
任何人都可以解释这种行为。 我想看看结构的内容是如何在内存中分配的。有没有更智能的方法来实现这一目标?
答案 0 :(得分:3)
您为指针的大小分配空间,而不是struct sockaddr_in
的大小。因此,您将超出分配边界并进入未定义的行为。
尝试:
record1 = malloc(sizeof(*record));
其次,如果要打印短片,则打印短片。考虑到你发送一个指针 - 取消引用(即一个struct-val)作为hex-int打印,我甚至对你的printf感到震惊,甚至工作。如果您正在尝试打印字节,则需要使用枚举算法来执行此操作。
unsigned char *p = (unsigned char*)record1;
for (size_t i=0; i<sizeof(*record1); ++i)
printf("%.2x ", p[i]);
是你可以这样做的一种方式。通过发布的main()
中的设置,可以生成:
10 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00
这当然有道理。 a
为16,而两字节短路中的little-endian确实为10 00
。同样,b
为4,同样,一个双字节无符号短,相同的小端,为04 00
。
答案 1 :(得分:2)
a
是short
,通常为2个字节长,b为unsigned short
,通常也为2个字节长。 %x
(printf样式格式化)中的一个字节长度为两个ASCII字符,因此2个字节长度为4个ASCII字符(使用%x
打印时)。因此,a
和b
一起最多可包含8个ASCII字符。无论如何,你打印结构内容的方式并不正确......你应该打印每个成员:
struct in_addr {
unsigned long s_addr; // load with inet_aton()
};
struct sockaddr_in {
short a;
unsigned short b;
struct in_addr c;
char d[8];
};
int main(int argc, char** argv) {
struct sockaddr_in *record1;
// record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in*));
record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
memset(record1, 0, 14);
record1->a = 16;
record1->b = 4;
//strcpy(record1->sin_zero, "1");
printf("Struct record1:\n");
printf(" a = 0x%04x\n", record1->a);
printf(" b = 0x%04x\n", record1->b);
printf(" c.s_addr = 0x%08x\n", record1->c.s_addr);
printf(" d = %02x %02x %02x %02x %02x %02x %02x %02x\n",
record1->d[0], record1->d[1], record1->d[2], record1->d[3],
record1->d[4], record1->d[5], record1->d[6], record1->d[7]);
}
答案 2 :(得分:0)
看着:
record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in*));
它可能不会做你想要的。您可能打算分配内存来保存sockaddr_in结构。该语句将为指针分配大小的内存为sockaddr_in。
正确的形式是(请注意,sizeof中的*已消失)
record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
现在它分配了正确的内存量。
在打印行中,你不能直接打印一个结构,你需要自己做一些艰苦的工作,
printf("Struct record1: %x %x %x %s", record1->a, record1->b, record->c.saddr, record1->d);
要将指针打印到record1,请使用类似的内容(注意*已经消失 - 您要打印指针,而不是它指向的指针)
printf("Struct record1: %x", record1);
如果要查看内存布局,可以使用类似
的内容char* address;
for (address = record1 ; address < (record1+sizeof(sockaddr_in)) ; address++)
{
printf("Address: %x Contents: %x\n", address, *address);
}
还有一件事,更喜欢使用sizeof()而不是“14”:
memset(record1, 0, sizeof(sockaddr_in));