sizeof() 面试题及其解析

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值