首页 > 编程语言 >C++面试八股文:聊一聊指针?

C++面试八股文:聊一聊指针?

时间:2023-06-17 22:32:32浏览次数:38  
标签:八股文 int 0x00001000 这块 C++ 地址 聊一聊 内存 师兄

某日二师兄参加XXX科技公司的C++工程师开发岗位第17面:

面试官:聊一聊指针?

二师兄:好的。

面试官:你觉得指针本质上是什么?

二师兄:这要从内存地址开始说起了。如果有一块容量是1G的内存,假设它的地址是从0x000000000x3fffffff,每一个字节都对应一个地址。当我们声明一个变量并初始化它时:

int a = 42;

二师兄:操作系统会分配一块容量为4(sizeof(int))的地址,这块内存的首地址是0x00001000(假设),结束地址是0x00001003,在申请的这4个字节上放入42。当我们对这个变量取地址时,

int a = 42;
int* p = &a;

二师兄:操作系统会再分配一块内存,这块内存的大小是sizeof(int*),这块内存的起始地址是0x00002000(假设),结束地址是0x00002003(32位操作系统),然后将&a取到的起始地址0x00001000放入0x00002000-0x00002003中。并将刚分配的这块内存的起始地址赋给p

指针

二师兄:当我们对p操作时,是对0x00002000-0x00002003这块内存操作,当我们对*p(解引用)操作时,是对0x00001000-0x00001003这块内存操作。

二师兄:回到问题,我觉得指针的本质就是内存地址。虽然指针指向一块内存地址,但它同时也是一个变量,也可以对指针取地址。如果对指针取地址,同样可以得到一个内存地址(如0x00002000),如果把这个内存地址存起来,那么指向这个内存地址的变量的类型就是二级指针(int**)。

面试官:好的。在0x00002000-0x00002003这块内存中,我们放入了一个地址是0x00001000,但是并没有这个地址的长度。只知道一个地址而不知道长度,怎么能把数据取出来?

二师兄:这主要是因为p的类型是int*,当对p解引用时,编译器知道了解引用的结果是int类型,所以从0x00001000往后读取4个字节(sizeof(int)),并按照当前CPU的模式(考虑大小端)把这四个字节组成一个int类型的变量。

面试官:malloc函数你知道吧,返回的类型是void*,在free的时候怎么知道这块内存的大小的呢?

二师兄:额。。这个还不太清楚。。

面试官:没关系,今天就到这里,回去等通知吧。

让我们来看看让二师兄折戟的这个问题:

malloc函数返回的类型是void*,在free的时候怎么知道这块内存的大小的呢?

这里牵扯到mallocfree的实现方式,不同的厂商实现的方式不尽相同。以ptmalloc为例,当使用malloc申请size = 16的内存时,malloc会从内存池中分配一块sizeof(chunk)+16长度的内存。chunk段保存了一些前后chunk的信息,也保存了这块内存的大小(16)。malloc函数返回的地址是0x00001000,而在free(0x00001000)时,free函数会用0x00001000减去特定值(sizeof(chunk)),得到chunk的起始地址,从chunk中获取这块内存真正的尺寸,从而完成free的任务。抛开内存的利用率不说,这是一个非常美妙的实现!

malloc

好了,今日份面试到这里就结束了。关注我,每天带你学习一个C++小知识!

关注我,带你21天“精通”C++!(狗头)

标签:八股文,int,0x00001000,这块,C++,地址,聊一聊,内存,师兄
From: https://blog.51cto.com/binarch/6506611

相关文章

  • C++面试八股文:聊一聊指针?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第17面:面试官:聊一聊指针?二师兄:好的。面试官:你觉得指针本质上是什么?二师兄:这要从内存地址开始说起了。如果有一块容量是1G的内存,假设它的地址是从0x00000000到0x3fffffff,每一个字节都对应一个地址。当我们声明一个变量并初始化......
  • C++增删改查+MySQL
    右键项目属性 点击编辑 选择mysql安装目录的include文件夹 包含了头文件之后包含库文件 点击编辑在mysql安装路径下面选择  选择编辑之后添加看这个文件下面有没有这个输入的文件依赖 有就代表成功连接数据库 创建数据库:createdatabasestudent_mana......
  • GESP-C++-4
    GESPC++四级样题卷在C++中,指针变量的大小(单位:字节)是()A.2B.4C.8D.与编译器有关答案:D以下哪个选项能正确定义一个二维数组()A.inta[][];B.charb[][4];C.doublec[3][];D.boold[3][4];答案:D在C++中,以下哪种方式不能用于向函数传递参数()A.值传递B.......
  • GESP-C++-3
    GESPC++三级样题卷下列关于负数的原码、反码、补码的描述中,正确的是()A.原码和反码互为按位取反(符号位除外),补码为反码加1B.原码和反码互为按位取反(符号位除外),补码为原码加1C.反码和补码互为按位取反(符号位除外),原码为反码加1D.补码和原码互为按位取反(符号位除外),反......
  • 【C++】值初始化
    如果自己建一个类,例如:classA{public:A(){cout<<"A"<<endl;}inti;};在main主函数中如下的两行代码:A*pa1=newA;A*pa2=newA();效果一样,都是调用A的构造函数,也就是说,自己定义的类,在new该类的对象时,所谓的值初始化是没有意义的。所......
  • GESP-C++-2
    GESPC++二级样题卷人们在使用计算机时所提到的Windows通常指的是()。A.操作系统B.多人游戏C.上市公司D.家居用具答案:A万维网WWW中存储了海量的数据资源,这里用于传输控制的协议是()。A.URLB.SMTPC.HTTPD.HTML答案:C下列关于C++语言的叙述,不正确的是()......
  • C++通讯录管理系统[2023-06-17]
    C++通讯录管理系统[2023-06-17]通讯录管理系统手机通讯录中的联系人的信息既可以存储在手机中,也可以存储在手机卡中,也可以同时存储在两个位置上(每个位置上的存储容量为1000,即手机卡中或手机上最多只能存储1000个联系人)。存储在手机中的联系人的信息只包含用户名和电话号码两项信......
  • GESP-C++-1
    GESPC++一级样题卷一、单选题(每题2分,共30分)人们在使用计算机时所提到的Windows通常指的是()。A.操作系统B.多人游戏C.上市公司D.家居用具答案:A计算机领域的图灵奖为了纪念()科学家图灵。A.英国B.德国C.瑞典D.法国答案:A下列关于C++语言的叙述,不......
  • c++线程安全队列--有锁
    C++线程安全队列是一种数据结构,用于在多线程环境中安全地共享数据。它提供了一组功能,确保多个线程可以同时读取和写入队列,而不会导致竞争条件或数据损坏。C++线程安全队列的常见功能:入队操作(Enqueue):将一个元素添加到队列的尾部。这个操作必须是原子的,以确保在多线程环境中不会......
  • UE/C++简单功能实现笔记
    本篇笔记主要用于记录如何利用C++在虚幻引擎5中实现一些基本的功能需求。目录实现功能与代码构造函数中添加物体运行时添加C++Actor运行时设置动态材质及参数蓝图调用C++函数蓝图访问C++成员C++调用用户控件蓝图函数播放wav格式音效实现功能与代码以下代码均来自我的跳棋小游......