sizeof的运用

来源:互联网 发布:现在淘宝店还好做吗 编辑:程序博客网 时间:2024/06/05 00:31


sizeof(a)返回的是系统对在内存中对a分配的内存空间大小,单位为字节。不同操作系统(windowLinux

以及不同位数(32位或64位)的系统内存分配策略(字节对齐)不同,因此sizeof的返回值也不相同。接下来我

们针对LinuxWindow两种操作系统进行分析。

在win32位和win64位机子上,各个基本对象所占空间大小如图所示:

C声明

Intel数据类型

X86-64

IA32

char

字节

1

1

short

2

2

int

双字

4

4

long int

四字

8

4

long long int

四字

8

8

char *

四字

8

4

float

单精度

4

4

double

双精度

8

8

long double

扩展精度

16

12

许多计算机系统对基本数据类型合法地址作出了一些限制,要求某种类型对象的地址必须为某个K(通常为24

8)的倍数。例如:假设一个操作系统总是从内存中取出8个字节数据,则其地址必须是8字节对齐的。

Linux沿用的对齐政策是,2字节数据类型(例如short)的地址必须是2的倍数,而较大的数据类型(例如int,

int*,floatdouble)的地址必须是4的倍数,这个要求就意味着一个short类型对象的地址最低位必须等于0.int

类型的对象和指针的地址的最低位必须都是0.

例如在Linux下,有如下数据结构:

struct P1

{

char w[3];

short s[3];

};

则该数据结构经过编译后存储方式如下(2字节对齐):上面数字为偏移量,下面为数据

 

       由于数据结构中含有short类型数据,所以short类型数据地址必须为2的倍数。则在Linux下,运用sizeof求得

的数据结构大小为:

sizeof(P1) = 10

考虑下面结构体

struct P2

{

int i;

char c;

char d;

int j;

};


其存储结构如下(8字节对齐):



数据结构中存在int型,其存储时是按照4字节对齐的,则sizeof(P2)=12.

 

对于Microsoft WIndows的对齐比较严格:任何K字节基本对象的地址都必须是K的倍数,K=24或者8.特别地,

它要求一个double或者long long类型数据的地址应该是8的倍数。这种要求提高了存储器性能,而代价是浪费了一

些空间。Linux8字节数据在4字节边界对齐。而数据类型long double,无论在Linux上还是window上都是4字节

对齐的。同理,在32Windows下,仍然

struct P3

{

char c;

short s;

};

则其存储结构为:

 

存在的最大数据对象short2字节,因此存储结构为2字节对齐,则sizeof(P3)= 4

 

struct P4

{

char c;

short s;

int i;

};

其存储结构为:

 

sizeof(P4) = 8.

 

对于下面这个数据结构,由于存在doublelong long类型,所以其存储时按照8字节对齐

struct foo

{

char* a;

short b;

double c;

char d;

float e;

char f;

long long g;

void* h;

};

 

分析其存储结构:

 

由于Cdouble类型,所以其地址必须为8的倍数,古需要在b后面填充两个字节。而efloat类型,其地址需要

4的倍数,因此17-20之间字节需要填充,而glong long型,其地址必须为8的倍数,所以f后边需要填充7

个字节。而void*占用四个字节,需要将其八字节对齐,因此需要补齐四字节。所以sizeof(foo) = 48.对于Win64

位的机器,其指针所占字节为8字节,因此当结构中存在指针时,也需要八字节对齐。



0 0