sizeof() 面试题及其解析
1.sizeof定义:
C++中的运算符,作用是返回变量、对象、以及数据类型所占内存的字节数。
延伸:sizeof和strlen的区别
1.strlen 是头文件 中的函数,sizeof 是 C++ 中的运算符
2.strlen 测量的是字符串的实际长度(其源代码如下),以 \0 结束。而 sizeof 测量的是字符数组的分配大小
char arr[10] = "hello";
cout << strlen(arr) << endl; // 5
cout << sizeof(arr) << endl; // 10
2.sizeof作用:
2.1 sizeof 处理基本数据类型
数据类型位数与编译器相关
如下:
![](https://img-blog.csdnimg.cn/f8c6492ee82b4b8ea4b887611b72c981.png
*所有指针同上
不过有意思的是我在vscode上测试时 long为4字节,指针型为8字节
如下所示:
int main()
{
cout<<sizeof(char)<<endl;
cout<<sizeof(int)<<endl;
cout<<sizeof(short)<<endl;
cout<<sizeof(long)<<endl;
cout<<sizeof(long long)<<endl;
cout<<sizeof(char*)<<endl;
cout<<sizeof(float)<<endl;
cout<<sizeof(double)<<endl;
return 0;
}
2.2sizeof 处理结构体
#include "stdio.h"
#include <iostream>
using namespace std;
typedef struct
{
char a:3;
char b:3;
char c:3;
char d:3;
char e:3;
}test1;
typedef struct
{
char a:3;
char b:4;
char c:5;
char d:6;
char e:7;
}test2;
typedef struct
{
char a:1;
char b:2;
char c:3;
char d:4;
char e:5;
}test3;
typedef struct{
int a;
char b;
char d;
long c;
}test4;
typedef struct{
int a;
char b;
long c;
char d;
}test5;
int main()
{
cout<<sizeof(test1)<<endl;
cout<<sizeof(test2)<<endl;
cout<<sizeof(test3)<<endl;
cout<<sizeof(test4)<<endl;
cout<<sizeof(test5)<<endl;
return 0;
}
运行结果:
分析:管理bit方式:8bit一组
C++对Byte管理方式:内存对齐
该编译器的对齐系数为8(32位为4,64位为8)
结构体内定义数据类型的顺序将影响分配长度
何为内存对齐:
现代计算机中内存空间都是按照字节(byte)进行划分的,所以从理论上讲对于任何类型的变量访问都可以从任意地址开始,但是在实际情况中,在访问特定类型变量的时候经常在特定的内存地址访问,所以这就需要把各种类型数据按照一定的规则在空间上排列,而不是按照顺序一个接一个的排放,这种就称为内存对齐,内存对齐是指首地址对齐,而不是说每个变量大小对齐
为什么要内存对齐:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
2.3 sizeof 处理字符串,char* char数组
string s = "hellohwc";
char * s1 = "hellohwc";
char s2[] = "hellohwc";
char s3[100];
char* s4=(char*)malloc(100);
void *s5=(void*)malloc(100);
cout<<sizeof(s)<<endl;
cout<<sizeof(s1)<<endl;
cout<<sizeof(s2)<<endl;
cout<<sizeof(s3)<<endl;
cout<<sizeof(s4)<<endl;
cout<<sizeof(s5)<<endl;
运行
s:编译器为string类型分配固定空间
s1:我的编译器为64位,为指针分配8字节(32位时为指针分配4字节)
s2:char型数组,结束符占一个字节,8+1 = 9
s3:数组长度为100,100*1=100
s4:为指针分配8字节
s5:同上
2.4 sizeof 处理 类
// testforyou.cpp : Defines the entry point for the console application.
//
#include "stdio.h"
#include <iostream>
#include <string>
using namespace std;
class emptyClass1{
public:
emptyClass1(){}
~emptyClass1(){}
};
class emptyClass2{
public:
emptyClass2(){}
virtual ~emptyClass2(){}
};
class hwcBase{
public:
hwcBase(){}
virtual ~hwcBase(){}
private:
int base;
};
class hwcSubFirst:hwcBase{
public:
hwcSubFirst():hwcBase(){}
~hwcSubFirst(){}
private:
int sub;
};
class hwcSubSecond:hwcBase{
public:
hwcSubSecond():hwcBase(){}
~hwcSubSecond(){}
private:
int sub;
char sub2;
};
int main()
{
cout<<sizeof(emptyClass1)<<endl;
cout<<sizeof(emptyClass2)<<endl;
cout<<sizeof(hwcBase)<<endl;
cout<<sizeof(hwcSubFirst)<<endl;
cout<<sizeof(hwcSubSecond)<<endl;
return 0;
}
1.空类,在内存中要存在一个标示来区分,分配一个字节
2.析构函数,指针(vptr)指针指向虚表,为指针分配8字节
3.hwcBase类,一个Int占用4Byte,一个指针(vptr)8Byte,考虑内存对齐,共占16Byte
4.hwcSubFirst,继承来一个Int,本身有一个Int,加上一个vptr指针,共16字节 (在处理内存对齐时先处理本身以及继承的数据类型,再处理指针)
5.继承的int,本身的int,本身的char 4+4+1,由于内存对齐,改为4+4+8,加上vptr,4+4+8+8 = 24(其实这里 vptr指针,继承int等的顺序还可以再细究一下——是否影响分配长度?)
参考博客:
关键字库函数:https://blog.csdn.net/weixin_44966641/article/details/124069032
关于sizeof的笔试面试题详解:https://blog.csdn.net/Hello_Hwc/article/details/41170719