1. sizeof是算符,strlen是函数。
2. sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''/0''结尾的。sizeof还可以用函数做参数,比如:
short f();
printf("%d/n", sizeof(f()));

输出的结果是sizeof(short),即2。
3. 数组做sizeof的参数不退化,传递给strlen就退化为指针了。
4. 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址
5. sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式

第一个例子:
char* ss = "0123456789";
sizeof(ss)
结果
4 ===》ss 是指向字符串常量的字符指针
sizeof(*ss)
结果 1 ===》*ss是第一个字符

char ss[] = "0123456789";
sizeof(ss)
结果 11 ===》ss是数组,计算到\0位置,因此是10+1
sizeof(*ss) 结果 1 ===》*ss是第一个字符

char ss[100] = "0123456789";
sizeof(ss)
结果是100 ===》ss表示在内存中的大小 100×1
strlen(ss)
结果是10 ===》strlen是个函数内部实现是用一个循环计算到\0为止之前

int ss[100] = "0123456789";
sizeof(ss)
结果 400 ===》ss表示再内存中的大小 100×4
strlen(ss)
错误 ===》strlen的参数只能是char* 且必须是以''\0''结尾的

char q[]="abc";
char p[]="a\n";
sizeof(q),sizeof(p),strlen(q),strlen(p);
结果是 4 3 3 2

第二个例子:
class X {
int i;
int j;
char k;
};
X x;
cout< 结果 12 ===》内存补齐
cout< 结果 12 同上

第三个例子:
char szPath[MAX_PATH]
如果在函数内这样定义,那么sizeof(szPath)将会是MAX_PATH,
但是将szPath作为虚参声明时(void fun(char szPath[MAX_PATH])),sizeof(szPath)却会是4(指针大小

内存对齐

许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。

例如,下面的结构各成员空间分配情况: 
struct test  { 
     char x1;      
short x2;      
float x3;      
char x4; 
};  
结构的第一个成员x1,其偏移地址为0,占据了第1个字节。第二个成员x2为short类型,其起始地址必须2字节对界,因此,编译器在x2和x1之间填充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上,在它们前面不需要额外的填充字节。在test结构中,成员x3要求4字节对界,是该结构所有成员中要求的最大对界单元,因而test结构的自然对界条件为4字节,编译器在成员x4后面填充了3个空字节。整个结构所占据空间为12字节。

参考链接:
http://blog.csdn.net/xiyangsl/article/details/2276029
http://wenku.baidu.com/view/ccbdda070740be1e650e9ac7.html

标签: 内存对齐,C++

添加新评论