您的位置:首页 > 其它

struct 内存对齐规则

2014-11-04 13:20 309 查看
struct 内存对齐规则

原文地址:/article/11446436.html

1 确定数据成员的offset地址

A-----基本数据类型(不包括数组/struct/class/uinon),起始offset地址,规律如下,sizeof(atom_type)*N (N=0,1,2,3..)

例子:char 0,1,2,3... int 0,4,8,12... double 0,8,16,24...

B-----组合数据成员(数组/struct/class/uinon ),,起始offset地址,规律如下,sizeof{max(atom_type)}*N (N=0,1,2,3...) 也就是成员的子成员中最大的那个,说到底还是依赖于基本数据类型的大小(找到它的所有基本类型,选出最大的)。

例子:char ch[5]; 0,1,2,3... strcut ss{int var1;double var2}; 0,8,16,24...

2 计算最终的大小,sizeof() 的时候,内部最大成员的"最宽基本类型成员"的整数倍,不足补齐,

例子 struct a{int a;double d;} 最宽基本数据类型成员大小为8,则a的大小只能是8的倍数。

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
//author: horizon
//date:2014年11月4日 13:22:58
struct C
{
double C_d;     //第2.3.1   数据类型为double,地址为32-39
char   C_char;   //第2.3.2   数据类型为char,地址为40-41
int    C_int;     //第2.3.3   数据类型为int,地址为4的倍数,地址为44-47
};
struct B
{
char B_array[5];  //第2.1步: B_array的地址确定为16-20
int  B_int;       //第2.2步: 数据类型为int,地址为4的倍数,地址为24-27
C  B_C;           //第2.3步, C的基本数据类型(double  char)中最大的为double,B_C的起始地址为8的倍数,起始地址为32
};
struct A
{

char A_ch[9];   //第一步:确定A_ch起始地址为0,占用地址0-8
B A_B;          //第二步:确定A_B的基本数据类型(char  int  double)最大为double,则B的起始地址为8的倍数,只能是16了,
double A_d;     //第三步:在2.3.3确定的47的基础上,8的倍数,地址范围为48-55
char A_char;    //第四步:地址为56-57
};  //根据sizeof规则,sizeof(A)为8的倍数,sizeof(A)=64>=57;  A的地址范围0-63

int _tmain(int argc, _TCHAR* argv[])
{
struct A a;

cout<<"sizeof(a): "<<sizeof(a)<<endl;

cout<<"A_ch 起始地址:"<<(char *)&a.A_ch[0]-(char *)&a<<endl;
cout<<"A_B 起始地址:"<<(char *)&a.A_B-(char *)&a<<endl;
cout<<"     B_array 起始地址:"<<(char *)&a.A_B.B_array[0]-(char *)&a<<endl;
cout<<"     B_int 起始地址:"<<(char *)&a.A_B.B_int-(char *)&a<<endl;
cout<<"     B_C 起始地址:"<<(char *)&a.A_B.B_C-(char *)&a<<endl;
cout<<"         C_d 起始地址:"<<(char *)&a.A_B.B_C.C_d-(char *)&a<<endl;
cout<<"         C_char 起始地址:"<<(char *)&a.A_B.B_C.C_char-(char *)&a<<endl;
cout<<"         C_int 起始地址:"<<(char *)&a.A_B.B_C.C_int-(char *)&a<<endl;
cout<<"A_d 起始地址:"<<(char *)&a.A_d-(char *)&a<<endl;
cout<<"A_char 起始地址:"<<(char *)&a.A_char-(char *)&a<<endl;

system("pause");
return 0;
}




如果任何错误的地方请指出,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: