来自leetcode C++面试突破
第一部分:编译&内存
1.ELF文件
.text section:代码段。通常存放已编译程序的机器代码,一般操作系统加载后,这部分是只读的。
.rodatasection:只读数据段。此段的数据不可修改,存放程序中会使用的常量。比如程序中的常量字符串
.datasection:数据段。主要用于存放已初始化的全局变量、常量。
.bsssection: bss 段。该段主要存储未初始化全局变量,仅是占位符,不占据任何实际磁盘空间。目标文件格式区分初始化和非初始化是为了空间效率
加载时依次读取并分配内存空间,用PC指示器指示代码段起始位置,然后启动进程。
2.内存分区
栈:目前绝大部分 CPU 体系都是基于栈来运行程序,栈中主要存放函数的局部变量、函数参数、返回地址等,栈空间一般由操作系统进行默认分配或者程序指定分配,栈空间在进程生存周期一直都存在,当进程退出时,操作系统才会对栈空间进行回收。
堆:动态申请的内存空间,就是由 malloc 函数或者 new 函数分配的内存块,由程序控制它的分配和释放,可以在程序运行周期内随时进行申请和释放,如果进程结束后还没有释放,操作系统会自动回收。我们可以利用
全局区/静态存储区:主要为 .bss 段和 .data 段,存放全局变量和静态变量,程序运行结束操作系统自动释放,在 C 中,未初始化的放在 .bss 段中,初始化的放在 .data 段中,C++ 中不再区分了。
常量存储区:.rodata 段,存放的是常量,不允许修改,程序运行结束自动释放。
代码区:.text 段,存放代码,不允许修改,但可以执行。编译后的二进制文件存放在这里。
总结:
栈——>存储所有数据,自动释放,申请效率高,不可控
堆——>存储周期数据,手动申请,手动释放,申请效率低,可控
静态存储区——>.bss .data, 全局和静态变量,自动释放
常量存储区——>.rodata,自动释放
代码区——>.text, 编译后的二进制文件,不可修改可运行。
3. 堆 和 栈
栈: 连续空间,有最大容量限制,线程安全,有溢出机制保护
堆:非连续空间,结构近似与链表,无最大容量限制,线程不安全
4.变量定义和生存周期
全局变量:具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。其他不包含全局变量定义的源文件需要用 extern 关键字再次声明这个全局变量。
静态全局变量:具有文件作用域。它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被 static 关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
局部变量:具有局部作用域。它是自动对象(auto),在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回,局部变量对于函数外部的程序来说是不可见的。当然内部实际更复杂,实际是以 {} 为作用域的。
静态局部变量:具有局部作用域。它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见, 只有定义该变量的函数内部可以使用访问和修改该变量。
比如以下文件定义
链接:https://leetcode.cn/leetbook/read/cmian-shi-tu-po/vvg9wc/
来源:力扣(LeetCode)