很快就要找工作了,大家都埋头在啃程序员面试宝典,突然发现sizeof大有研究,平时分配对象内存的时候也用到,但是发现还有很多不会的地方,不多说,下面简单介绍一下我总结的。
sizeof:求对象或类型所占的内存字节数
union U
1、一般(32位机器),char型占1个字节,int型占4个字节,float占4个字节,double型占8个字节,string占4个字节
2、指针变量的sizeof:
在32位计算机中,一
个指针变量的返回值必定是4(以字节为单位),可以预计,在将来的64位系统
中指针变量的sizeof结果为8。 例如:
char
* pc =
"abc"
;
int
* pi;
string* ps;
char
** ppc = &pc;
void
(*pf)();
//
函数指针
sizeof
( pc );
//
结果为
sizeof
( pi );
//
结果为
sizeof
( ps );
//
结果为
sizeof
( ppc );
//
结果为
sizeof
( pf );
//
结果为
|
3、数组的sizeof:
数组的sizeof值等于数组所占用的内存字节数,如:
char
a1[] =
"abc"
;
int
a2[3];
sizeof
( a1 );
//
结果为
*1=4
,字符串末尾还存在一个
NULL
终止符
sizeof
( a2 );
//
结果为
*4=12
(依赖于
int
)
|
4、结构体的sizeof:
对于结构体使用sizeof时一般遇到字节对齐,字节对齐一般有三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有 需要编译器会在成员之间加上填充字节;
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一 个成员之后加上填充字节
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有 需要编译器会在成员之间加上填充字节;
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一 个成员之后加上填充字节
根据这个准则我们看个例子:
struct
S1
{
char
c;
int
i;
};
char占1个字节,int占4个字节,根据准则第二条我们在char所占字节后增加3个字节,得到sizeof(s1)为8
到这里了不要高兴得太早,有一个
影响sizeof的重要参量还未被提及,那便是编译器的pack指令。它是用来调整结构体对齐
方式的,不同编译器名称和用法略有不同,VC6中通过#pragma pack实现,也可以直接修改
/Zp编译开关。#pragma pack的基本用法为:#pragma pack( n ),n为字节对齐数,其取值
为1、2、4、8、16,默认是8,如果这个值比结构体成员的sizeof值小,
那么该成员的偏移
量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值。
5、联合体的sizeof:
结构体在内存组织上是顺序式的,联合体则是重叠式,各成员共享一段内存,所以整个联
合体的sizeof也就是每个成员sizeof的最大值。结构体的成员也可以是复合类型,这里,
复合类型成员是被作为整体考虑的。
所以,下面例子中,U的sizeof值等于sizeof(int)。
union U
{
int
i;
char
c;
};
6、类的sizeof:
分几种情况:
1)空类(类中没有成员)的sizeof为1,例如:
class
A
{
public
:
A(){}
~A(){}
void
fun(){}
};
sizeof(A)是1.
2)有成员变量时,则大小为非静态成员变量经过对齐所占的空间(静态变量存放在全局数据区),则对齐方式与结构体相同,例如:
class
A
{
public
:
int
b;
float
c;
char
d;
};
sizeof(A)是12.
class
A
{
public
:
static
int
a;
int
b;
float
c;
char
d;
};
sizeof(A)是12
3) 若类中含有虚函数,则无论有几个虚函数,则结构为sizeof(成员变量)+sizeof(4,V表指针),例如:
class
Base
{
public
:
Base(){cout<<
"Base-ctor"
<<endl;}
~Base(){cout<<
"Base-dtor"
<<endl;}
int
a;
virtual
void
f(
int
) {cout<<
"Base::f(int)"
<<endl;}
virtual
void
f(
double
){cout<<
"Base::f(double)"
<<endl;}
};
siz
eof(Base)为8
4)对于有继承的情况。。。未完待续