C/C++你必须知道的小知识(10)

181 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

1.2.3 malloc和局部变量分配在堆还是栈?

参考回答

​ malloc是在堆上分配内存,需要程序员自己回收内存;局部变量是在栈中分配内存,超过作用域就自动回收。

1.2.4 程序有哪些section,分别的作用?程序启动的过程?怎么判断数据分配在栈上还是堆上?

参考回答

image-20201219142935577

一个程序有哪些section:

如上图,从低地址到高地址,一个程序由代码段、数据段、  BSS 段组成。

  1. 数据段: 存放程序中已初始化的全局变量和静态变量的一块内存区域。

  2. 代码段: 存放程序执行代码的一块内存区域。只读,代码段的头部还会包含一些只读的常数变量。

  3. BSS 段:存放程序中未初始化的全局变量和静态变量的一块内存区域。

  4. 可执行程序在运行时又会多出两个区域:堆区和栈区。

    堆区: 动态申请内存用。堆从低地址向高地址增长。

    栈区: 存储局部变量、函数参数值。栈从高地址向低地址增长。是一块连续的空间。

  5. 最后还有一个文件映射区,位于堆和栈之间。

程序启动的过程:

  1. 操作系统首先创建相应的进程并分配私有的进程空间,然后操作系统的加载器负责把可执行文件的数据段和代码段映射到进程的虚拟内存空间中。
  2. 加载器读入可执行程序的导入符号表,根据这些符号表可以查找出该可执行程序的所有依赖的动态链接库。
  3. 加载器针对该程序的每一个动态链接库调用LoadLibrary
    (1)查找对应的动态库文件,加载器为该动态链接库确定一个合适的基地址。
    (2)加载器读取该动态链接库的导入符号表和导出符号表,比较应用程序要求的导入符号是否匹配该库的导出符号。
    (3)针对该库的导入符号表,查找对应的依赖的动态链接库,如有跳转,则跳到3
    (4)调用该动态链接库的初始化函数
  4. 初始化应用程序的全局变量,对于全局对象自动调用构造函数。
  5. 进入应用程序入口点函数开始执行。

怎么判断数据分配在栈上还是堆上: 首先局部变量分配在栈上;而通过malloc和new申请的空间是在堆上。