面试题之C++进程如何内存管理

820 阅读3分钟

大家好,我是编程熊,字节跳动、旷视科技前员工,ACM金牌,和大家一起学习面试题。

C++进程内存如何管理?

这是一道来自百度的后端开发一道面试题,也是面试中很常见的问题,今天和大家一起深入的学习一下。

首先涉及到内存管理,不得不提到 虚拟内存,因为它是操作系统对内存的抽象,C++进程内存管理也是在此基础之上。

虚拟内存: 是一个抽象的概念,为每个进程了一个假象,即每个进程都独占的使用主存。每个进程看懂的内存都是一致的。

操作系统进程分配的是虚拟内存,虚拟内存的地址与处理器的位数有关,32位的处理器最大可以寻址的内存空间为不到4G,64位处理器理论上可以处理 2^64B 的内存空间,处理能力取决于CPU的地址总线数量

操作系统的虚拟地址空间可以分为以下几个部分,从上到下(最下面是地址的开始位置)依次为:

  1. 内核虚拟地址: 为内核保留的。不允许应用程序读写这个区域的内容或者直接调用内核代码定义的函数。
  2. 栈: 栈区域是用户虚拟空间的顶部,编译器用其实现函数调用,用户栈在程序执行期间可以动态的扩展和收缩。
  3. 共享库: 虚拟地址空间的中间是存放共享库的代码和数据(比如,C标准库和数据库)。
  4. 堆: 共享库的下面是运行时堆。代码和数据区在进程开始运行时的时候,就被指定了大小,但与代码和数据区 不同,堆是进程运行时动态地申请或释放(比如,malloc、free)。
  5. 程序代码和数据: 对所有进程来说,代码是从同一固定地址开始的,紧接着的和C全局变量相对应的数据位置。代码和数据区是直接按照可执行目标文件的内容初始化的。
image-20210714162137727

知道了操作系统的虚拟内存之后,我们就可以对C++内存管理有一个更好的理解。

C++进程的内存,分为五个区域:

  1. 栈区:编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。未free的内存,程序结束后由OS回收。
  2. 堆区:newdelete动态管理的内存区域。未delete的内存,程序结束后由OS回收。
  3. 自由存储区:mallocfree 动态管理的内存区域,和堆很相似。
  4. 全局区(静态区): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域数据段;未初始化的全局变量和未初始化的静态变量在相邻的另一块区域bss段。
  5. 常量存储区: 存放的是常量,不允许修改。

image-20210714164433499

下面以一段C++代码为例,展示数据在内存中存放的位置。


class A {
  int num;
}

static int a;    //全局&静态变量区 
int  b=0;        //全局&静态变量区 

int  main()    
{   
  char  s[]="abc";        //栈    
  char  *p="123456";  //123456在常量区,p在栈上。    

  p1=  (char  *)malloc(10);  // 堆
  A *a = new A();              // 堆
}    

最后

如果对你有所帮助,希望『点赞』,『转发』,『关注』三连一下~

微信公众号: 『编程熊』,分享面试知识、算法、靠谱内推、进交流群~

公众号后台回复【书】,免费领取计算机学习核心资料。

我是编程熊,我们下期见~