怎样像访问结构体一样访问字符数组?或者让结构体没有内存对齐
很多网络协议都有发送规定的字符串过去,都明确规定了第几个字节(或者叫字段)表示什么意义。按理说既然有各个字段,用结构体表示很合抽象逻辑。
可是结构体有内存对齐,接收方和发送方默认的偏移不一样的话,就会解释出错。所以还是只能用字符串,一个字节一个字节的访问。可能会用指针移来移去。
怎样才能像结构体一样访问各个字段,又能想字符数组一样发送和接收呢?这是不是没有内存对齐的结构体,结构体可以没有内存对齐吗?
[解决办法]
#pragma pack(1)
struct Node{
int a;
char b;
int c;
};
#pragma pack()
[解决办法]
内存对齐是必须的,关键是以几个字节对齐的问题,1个,4个,8个?
[解决办法]
为什么会有内存对齐
以下内容节选自《Intel Architecture 32 Manual》。
字,双字,和四字在自然边界上不需要在内存中对齐。(对字,双字,和四字来说,自然边界分别是偶数地址,可以被4整除的地址,和可以被8整除的地址。)
无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。
一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问。
某些操作双四字的指令需要内存操作数在自然边界上对齐。如果操作数没有对齐,这些指令将会产生一个通用保护异常(#GP)。双四字的自然边界是能够被16整除的地址。其他的操作双四字的指令允许未对齐的访问(不会产生通用保护异常),然而,需要额外的内存总线周期来访问内存中未对齐的数据。
[解决办法]
网络协议呀,用pragma pack(1)不是太好。大家都这样写:
#include <stdio.h>
int main()
{
struct Node
{
int a :32;
char b :8;
int c :32;
};
struct Node node;
printf("%u\n", sizeof(node));
return 0;
}
后边的数为bit数。结合#pragma pack(1)应该更完美!
[解决办法]
可以用#pragma pack(1)。。这样结构体中的数据就会连续存储。。