sizeof常见情况
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
stuct{
short a1;
short a2;
short a3;
}A;
stuct{
short a1;
long a2;
short a3;
}B;
int main();
{
char* ss1 = "0123456789";
char ss2[] = "0123456789";
char ss3*[100] ="0123456789";
int ss4[100];
char q1[] = "abc";
char q2[] = "a\n";
char* q3 = "a\n";
char *str1 = (char *)malloc(100);
void *str2 = (void *) malloc(100);
cout<< size of(ss1) <<" " ;
cout<< size of(ss2) <<" " ;
cout<< size of(ss3) <<" " ;
cout<< size of(ss4) <<" " ;
cout<< size of(q1) <<" " ;
cout<< size of(q2) <<" " ;
cout<< size of(q3) <<" " ;
cout<< size of(A) <<" " ;
cout<< size of(B) <<" " ;
cout<< size of(str1) <<" " ;
cout<< size of(str2) <<" " ;
return 0;
}
ss1是一个字符指针,指针的大小是一个定值,就是4字节,所以答案为4;
ss2是一个字符数组,但是未定义大小,所以默认数组有\0,所以是11字节;
ss3也是一个字符数组,但是规定了大小,所以就是100字节;
ss4是一个整型数组,这个数组规定了大小,整型变量占4字节,所占空间是4*100字节,400字节;
q1和ss2类似,所以4字节;
q2有"\n",算一位(\0),所以是3字节;
q3是整形指针,指针的大小是个定值,所以是4字节;
A B是两个结构体。
A是三个short整型,各自2字节对齐,sizeof(A)为6.
B中a1虽然为short类型2要与下方的long类型对齐所以为四字节,a2为四字节,a3和a1一样需要和内存对齐,所以最后为12字节。
str1和str2都是指针,所以都是4字节。
数据对齐
数据对齐是指数据所在的内存地址必须是该数据长度的整数倍。DWORD数据的内存地址能被4除尽,WORD数据的内存起始地址能被2除尽。DWORD:2个字节就是1个Word(1个字,16位),DWORD(Double Word)就是双字的意思,两个字(32位)。x86CPU能直接访问一个对齐的数据,当他访问一个未对齐的数据时,会在内部进行一部分的调整。
这些调整对于程序来说是透明的,但是会降低运行速度,所以编译器在编译程序时会尽量保证数据对齐。
静态变量对sizeof的影响
我们先来看这样一个例子
#include<iostream>
using namespace std;
class A
{
public:
int a;
static int b;
}
int main()
{
cout<< sizeof(A)<<endl;
}
请问这个程序打印的值是多少?
答案是4字节。为什么呢?原因就是静态变量是放在全局数据区的,而sizeof计算的是栈中分配的大小,是不会计算在内的,所以结果是4.
sizeof和strlen的区别
1)sizeof操作符的结果是 size_t,它在头文件的typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。
2)sizeof 是运算符,strlen是函数。
3)sizeof可以用类型做参数,strlen只能用char做参数,且必须“\0”结尾的。sizeof还可以用函数做参数,比如
short f();
printf("%d\n",sizeof(f()));
输出的结果是sizeof(short),即2。
4)数组做sizeof的参数不会退化,但是传递给stelen会退化成指针;
5)大部分编程在编译的时候就计算过了字符串的长度。这就是sizeof(x)可以用来定义数组的原因;
6)strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型.内存的大小
7)sizeof后如果是类型必须加括号,如果是变量名可以不加。这是因为sizeof是操作符而不是个函数;
8)数组作为参数传递给函数传递的是指针而不是函数,传递的是首地址,在c++中传递数组传递永远是首地址元素的指针编译器不知道数组的大小。
9)sizeof操作符不能用于函数类型,不完全的类型或位字段。不完全类型值具有未知大小的数据类型,如未知储存的数组大小类型、未知的内容的结构或类型,void类型等。
空类的所占空间
我们先来看看这个程序
#include<iostream>
#include<memory.h>
#include<assert.h>
using namespace std;
class A
{
};
class A2
{
};
class B :public A
{
};
class C :public virtual B
{
};
class D :publicA ,public A2;
int main(int argc,char *argv [])
{
cout<<"sizeof(A):"<sizeof(A)<<endl;
cout<<"sizeof(A):"<sizeof(B)<<endl;
cout<<"sizeof(A):"<sizeof(C)<<endl;
cout<<"sizeof(A):"<sizeof(D)<<endl;
}
return 0;
以上答案是1,1,4,1,。这说明空类所占的空间为1.单一继承的空类空间也为1,多重继承的空类空间也为1.但是虚继承涉及虚表(虚指针),所以sizeof(C)的大小为4.