sizeof 与结构体大小及结构体对齐问题, 字节对齐

来源:互联网 发布:js获取时间的日期部分 编辑:程序博客网 时间:2024/04/29 19:47
遇到了这样的情况
有如下结构体
struct ST_1{      char a;      double b;      char c;};

 

1. 写入文件

ST_1 st;st.a = 'a';st.b = 123.4;st.c = 'b';fwrite(&st, sizeof(ST_1), 1, file);
 

2. 从文件中读出来

ST_1 st;fread(&st.a, sizeof(char), 1, file);fread(&st.b, sizeof(double), 1, file);fread(&st.c, sizeof(char), 1, file);
但是这样子读出来的结果是错误的. 而必须这样子读取
fread(&st, sizeof(ST_1), 1, file);

什么原因, 很明显是读取错位了. 什么原因造成错位? 这就是与结构体对齐有关.


看下面例子

struct ST_2{      char a;       // 位置在0, 大小是1      double b;   // 位置在8  大小是8      char c;      // 位置在16 - 1};     // 总大小是 24 (sizeof(char) + sizeof(double) + sizeof(char) = 10 != 24
1. 首先, 一个结构体的大小是按照结构体中大小最大的那个字段对齐的.
    例如ST_2 是按照sizoef(double)大小对齐的(也就是8Byte).


2. 每个字段的开始位置都要在其大小的整数倍位置.
    例如: ST_2.b, 大小为8Byte, 但是ST_2.a大小为1Byte, 所以ST_2.b的位置在8, 前面7个Byte就不要了.

#include "stdafx.h"#include <iostream>// 默认是以该结构中占最大字节数那个类型大小对齐// 12struct ST_0{char a;// 1int b;// 4char c;// 1};// 以结构中最大的那个变量的大小对齐, 这里是4字节对齐//|--|--|--|--||--|--|--|--||--|--|--|--|//|01|02|03|04||01|02|03|04||01|02|03|04|//|--|--|--|--||--|--|--|--||--|--|--|--|//|a  00 00 00||b  b  b  b ||c  00 00 00|//|--|--|--|--||--|--|--|--||--|--|--|--|struct ST_0_0{ST_0 a;char d;};// 以结构中最大的那个变量的大小对齐, 这里是4字节对齐//|--|--|--|--||--|--|--|--||--|--|--|--||--|--|--|--|//|01|02|03|04||01|02|03|04||01|02|03|04||01|02|03|04|//|--|--|--|--||--|--|--|--||--|--|--|--||--|--|--|--|//|a  00 00 00||b  b  b  b ||c  00 00 00||d  00 00 00|//|--|--|--|--||--|--|--|--||--|--|--|--||--|--|--|--|// 24struct ST_1{char a;// 1double b;// 8char c;// 1};// 以结构中最大的那个变量的大小对齐, 这里是8字节对齐//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|//|01|02|03|04|05|06|07|08||01|02|03|04|05|06|07|08||01|02|03|04|05|06|07|08|//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|//|a  00 00 00 00 00 00 00||b  b  b  b  b  b  b  b ||c  00 00 00 00 00 00 00|//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|// 16struct ST_2{double b;// 8char a;// 1char c;// 1};// 以结构中最大的那个变量的大小对齐, 这里是8字节对齐//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|//|01|02|03|04|05|06|07|08||01|02|03|04|05|06|07|08|//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|//|b  b  b  b  b  b  b  b ||a |c |00|00|00|00|00|00|//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|// 16struct ST_3{double b;// 8char a;// 1char c;// 1char d;// 1};// 以结构中最大的那个变量的大小对齐, 这里是8字节对齐//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|//|01|02|03|04|05|06|07|08||01|02|03|04|05|06|07|08|//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|//|b  b  b  b  b  b  b  b ||a |c |d |00|00|00|00|00|//|--|--|--|--|--|--|--|--||--|--|--|--|--|--|--|--|#pragma pack(1)// 10struct ST_4{char a;// 1double b;// 8char c;// 1};// 设置成1字节对齐//||--||--||--||--||--||--||--||--||--||--||//||01||01||01||01||01||01||01||01||01||01||//||--||--||--||--||--||--||--||--||--||--||//||a ||b ||b ||b ||b ||b ||b ||b ||b ||c ||//||--||--||--||--||--||--||--||--||--||--||// 10struct ST_5{double b;// 8char a;// 1char c;// 1};// 设置成1字节对齐//||--||--||--||--||--||--||--||--||--||--||//||01||01||01||01||01||01||01||01||01||01||//||--||--||--||--||--||--||--||--||--||--||//||b ||b ||b ||b ||b ||b ||b ||b ||a ||c ||//||--||--||--||--||--||--||--||--||--||--||#pragma pack()int _tmain(int argc, _TCHAR* argv[]){std::cout << "ST_0 :" << sizeof(ST_0) << std::endl;std::cout << "ST_0_0 :" << sizeof(ST_0_0) << std::endl;std::cout << "ST_1 :" << sizeof(ST_1) << std::endl;std::cout << "ST_2 :" << sizeof(ST_2) << std::endl;std::cout << "ST_3 :" << sizeof(ST_3) << std::endl;std::cout << "ST_4 :" << sizeof(ST_4) << std::endl;std::cout << "ST_5 :" << sizeof(ST_5) << std::endl;return 0;}

原创粉丝点击