小结sizeof和strlen的使用以及类中的内存分布
1,区别小结
-
sizeof()是运算符,strlen()是库函数
-
sizeof()在编译时计算好了,strlen()在运行时计算
-
sizeof()计算出对象使用的最大字节数,strlen()计算字符串的实际长度
-
sizeof()的参数类型多样化(数组,指针,对象,函数都可以),strlen()的参数必须是字符型指针(传入数组时自动退化为指针)
2,实例讲解
sizeof()是运算符,strlen()是库函数
sizeof()在编译时计算好了,strlen()在运行时计算
sizeof()计算出对象使用的最大字节数,strlen()计算字符串的实际长度
sizeof()的参数类型多样化(数组,指针,对象,函数都可以),strlen()的参数必须是字符型指针(传入数组时自动退化为指针)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char str[50] = "hello world";
printf("strlen(str)=%d\n",strlen(str)); // strlen(str)=50
printf("sizeof(str)=%d\n",sizeof(str)); // sizeof(str)=11
return 0;
}
strlen在计算字符的个数时,不会将’\0’算入,但是必须包含’\0’,而且只能以char*(字符串)做参数;
sizeof计算类型所占空间的字节数,在数组名做参数时计算的是整个数组的大小;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char str[20] = "hello world";
char *s = (char *)malloc(20);
strcpy(s, str);
printf("strlen(s)=%d\n",strlen(s)); //strlen(s)=11
printf("sizeof(s)=%d\n",sizeof(s)); //sizeof(s)=4
free(s);
return 0;
}
sizeof在计算(char*)时,只是指针的大小,而不能返回动态地被分配的空间;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char p[] = {'a','b','c','d','e','f','g','h'};
char q[] = {'a','b','c','d,'\0','e','f','g'};
sizeof(p); //结果是8 p表示在内存中的大小 8×1
strlen(p); //为一个随机值,结果与编译器有关
sizeof(q); //结果是8 p表示在内存中的大小 8×1
strlen(q); //结果为4 存在'\0',遇到'\0'计算停止。
3,sizeof在struct/class中的使用
类所占的空间,需要注意以下几点:
3.1,内存字节对齐;
3.1.1 默认原则
每个成员相对于这个结构体变量地址的偏移量正好是该成员类型所占字节的整数倍,且最终占用字节数为成员类型中最大占用字节数的整数倍
3.1.2 继承关系
基类的成员在派生类的前面,在计算好基类所占的字节数后,紧接着是派生类。基类成员所占的字节只能由基类使用,派生类不能占用;在派生类中成员的分布只需满足每个变量起始字节序号为该类型所占字节数的整数倍且最终大小为占用字节数最大的类型对应的字节数的整数倍
3.1.3 关联关系
必须满足:1.结构体/类与结构体/类之间不会共用自动补齐的内存,即一个结构体变量/对象对齐之后填补的内存不允许被其他变量/对象占用;2.结构体的起始字节位置必须是该结构体中所占字节数最大的变量的字节数的整数倍;3.最终所占字节数必须是最大所占字节数最大的变量的字节数的整数倍。
3.1.4 强制对齐
使用#pragma pack(n)来设定以n字节对齐的方式(n可取2的较小次幂,即1,2,4,8,具体取值范围以及默认值与所使用的编译器有关。笔者所测试的环境下vs/vc默认为8,gcc默认为4)。
n字节对齐就是说变量存放的起始地址的偏移量有两种情况:
第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式;
第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
3.2,C++类的内存分布结构
3.2.1选中cpp属性
在visual studio 中,选中好cpp文件,右键选择属性;
3.2.2添加命令行
命令行中,如果写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1 reportSingleClassLayoutXXX(XXX为具体的类名),则只会打出指定类(XXX)的内存布局。