乐趣区

关于c++: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 放入 0x000020000x00002003 中。并将刚调配的这块内存的起始地址赋给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 的工作。抛开内存的利用率不说,这是一个十分美好的实现!

![]()

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

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

退出移动版