最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

焦点精选!C++ sizeof与strlen,并借此明晰内存对齐

来源:博客园

前言

sizeof()strlen()都是为了获取对象的长度。在正常编写C++的算法程序代码时,可能这两个都很少用到,因为各种stl容器的封装已经给了我们很大的便利,比如我们在想要获取自定义的vector容器里的元素个数,想要获取string类型的字符串的长度时,都只需要调用他们的.size()方法就可以得到容器的长度或者元素的个数。诚然如此,仍会有很多情况需要获取未定义大小方法的对象的大小,比如一个结构体,所以我们还是需要关注这些偏底层的知识,下面就来细细阐述:

sizeof()使用

sizeof() 计算的是变量或类型所占用的内存字节数, 而strlen计算的只能是变量的长度;

#includeusing namespace std;struct Node{    int val1;  // 4 bytes    int val2; // 4 bytes    Node* left; // 8bytes    Node* right; // 8 bytes};int main(){    cout<<"int:"<

总结:sizeof对于所有的指针,无论指针类型是什么,其所计算的都是指针本身也就是存储的地址值的长度,而对于64位机器,8 bytes足以访问其所有的内存地址(32位机器是4 bytes)。而对于字符数组类型,会自动计算在其末尾的"\0"运算符,是比strlen()多一个单位的。对于一个自定义结构体,会自动计算所有成员变量的和。从上可以看出对于两个int类型,两个指针类型他们的字节数分别是4, 4, 8, 8,于是总大小为24bytes。但此时有一个问题,如果把第二个int换为char,答案就是21 bytes了吗?答案是否定的,仍然是24 bytes,这就是内存对齐所导致的结果,sizeof()的值就是对齐之后的值。关于对齐可以参考:https://zhuanlan.zhihu.com/p/30007037此处放几个截图可以清晰的说明内存如何对齐(以四字节为对齐标准):


(相关资料图)

其对齐后的内存布局分别如下:

另外还需注意的是关于最后是否补齐为4或8字节的整数倍还是依具体平台而定。自测如下结构体,只占3字节并未补齐,但是运行x2却发现又补齐了,颇为奇怪:

struct Test{    char c1;    char c2;    char c3;}test;

strlen()使用

strlen()是函数,只能去计算以空字符"\0"结尾的字符串,否则是未定义的行为,所以他无法去计算结构体的大小。定义如下:

size_t strlen ( const char * str );(参数中只能传递字符串类型)

具体使用:

char s[] = "Hello, world!";strlen(s) // 输出 13,即字符串 s 中有 13 个字符(不包括结尾的空字符 "\0")

区别

那么除了上述用法和结果上的一些区别,即sizeof可以用在任意类型与对象,统计全部的字符大小包括"\0", 而strlen只能统计字符串的长度(不统计"\0").在底层实现时也有一些区别:

sizeof()是运算符,strlen()是库函数sizeof()在编译时计算好了,strlen()在运行时计算sizeof()计算出对象使用的最大字节数,strlen()计算字符串的实际长度sizeof()的参数类型多样化(数组,指针,对象,函数都可以),strlen()的参数必须是字符型指针(传入数组时自动退化为指针)

其实两者之前共同点就只在于都可以计算字符数组的长度,其他尽不相同。

关键词: