这里我想读取输入到struct dev的数据,所以我使用temp =(dev *)输入从char *转换为dev *。在我的机器上,行 printf(“%p \ n”,temp); 打印出0x804a040,如果为真,则行 printf(“%p \ n”,temp + 1) ); 应打印出0x804a04b,但它打印0x804a04c。行 printf(“%p \ n”,& temp-> size); 应打印出0x804a047,但它打印为0x804a048。
Plz帮助我弄清楚我误解或错误
@all:感谢所有人的帮助。我知道了。我读过一些帖子和solusion正在使用#paragma pack(1)或者像这样的指令。但它也是劝阻,因为它会减慢前任的处理速度。那么,还有其他任何想法。
感谢!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dev
{
short id;
char name[5];
int size;
} dev;
char input[] = { 0x03, 0x00, 0x65, 0x67, 0x03, 0x00, 0x43, 0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x65, 0x67, 0x03, 0x00, 0x43, 0x43, 0x00, 0x43, 0x00,
0x03, 0x00, 0x65, 0x67, 0x03, 0x00, 0x43, 0x43, 0x00, 0x43, 0x00,
0x03, 0x00, 0x65, 0x67, 0x03, 0x00, 0x43, 0x43, 0x00, 0x43, 0x00 };
int
main (int argc, char *argv[])
{
dev* temp;
temp = (dev*)input;
printf("%p\n", temp);
printf("%p\n", temp+1);
printf("%d\n", temp->id);
printf("%p\n", &temp->name[4]);
printf("%p\n", &temp->size);
temp++;
printf("%d\n", temp->id);
return 0;
}
答案 0 :(得分:3)
typedef struct dev
{
short id;
char name[5];
int size;
} dev;
可能与您认为的不一致。有编译器相关的填充 在田野之间。谷歌“struct padding”或类似的东西。
这应该显示字段偏移量:
dev foo;
printf("offset of id is %d\n", (char *)&foo.id - (char *)&foo);
printf("offset of name is %d\n", (char *)&foo.name[0] - (char *)&foo);
printf("offset of size is %d\n", (char *)&foo.size - (char *)&foo);
答案 1 :(得分:1)
答案非常简单:每个结构项的大小总和为11个字节,但出于性能原因,“int size”被置于可被4整除的地址。
所以'结构中的大小偏移应该是7但是为8(因为8是可以被4整除的更接近的数字),所以最终大小为12。
您可以强制编译器打包struct。对于gcc,你可以这样做:
typedef struct dev
{
short id;
char name[5];
int size;
} dev __attribute__ ((packed));
答案 2 :(得分:0)
temp+1
应该保留下一个开发者的位置。此处sizeof(dev)
为12,因此temp +1
应该基本上位于0x804a04c
,因为(0x804a040-0x804a04b)
是为第一个开发者保留的。
大小为12,因为为了优化,编译器分配的内存为4的倍数。这是32位架构中的典型优化技术。 实际上你的内存分配很可能是ike:
<char><char><char><char>
<char><short><padding>
<int>
总大小为12
答案 3 :(得分:0)
对齐。数据通常会在字大小边界上对齐,因为它是处理器读取和提高性能的“自然”大小。
在这种情况下,结构的大小为11个字节。填充到12。
答案 4 :(得分:0)
您已经假定编译器已经组装了没有填充的结构。检查sizeof(dev)
,这不符合您的想法。
填充的目的是在字(4字节)边界上对齐int成员字段 - 因为short是2而“name”是5,所以在name
和{之间有一个填充字节{1}}。
一种解决方案是使size
6个字节。这并不能保证一些奇怪的编译器不会做一些奇怪的事情 - 但这似乎不太可能。您还可以使用编译器特定的“pack”编译指示。
最佳解决方案可能是将输入复制映射到字段中。