今天看C++ Primer Plus时,看到其中有一条。使用new[]运算符创建数组时,在使用完后应该用delete[]来释放占用的内存区域。但是使用int tacos[10];这样的语句时,就不需要手动释放内存。从这里我就对C++编译器是如何处理内存区域产生了兴趣,今天就先做一个初步了解。
C++运行时内存区域
其可以分为五块内存区域,分别是栈(Stack),堆(Heap),全局/静态区(Global/Static),常量区(Text Segment/ROData)和代码区(Code Segment)。
- 栈
- 自动变量:局部变量,函数参数等会存储在栈上。当函数调用的时候会创建一个栈帧,栈帧分配用于存储这些变量。当函数结束的时候栈帧会销毁,这时变量也随之销毁。
- 特点:栈的内存分配很快,同时由C++编译器自动管理,但是空间比较有限,通常就只有几MB。
- 堆
- 动态分配的内存:使用malloc,calloc或者new分配的内存位于堆上。这部分内存区域需要程序员进行手动内存管理。对于malloc与calloc申请的内存,需要使用free进行释放。对于new申请的内存,需要使用delete进行释放。
- 特点:堆空间比较大,但是分配速度较慢。
- 全局/静态区
- 全局变量:定义在函数外部的变量,作用于为整个程序,存储在全局/静态区。
- 静态变量:使用static修饰的变量,即使定义在函数内部,生命周期也是整个程序运行期间。该变量也是存储在全局/静态区。
- 特点:内存会一直保留,直到程序结束为止。
- 常量区
- 字符串字面值:如
"Hello,World"这样的字符串就会存储在常量区,这时只读不可修改的。 - const修饰的变量:这种类型的变量也可能存储在常量区,具体取决于编译器的具体实现。
- 字符串字面值:如
- 代码区
- 函数代码:编译后的程序代码会存储在代码区,程序执行的时候就从这里读取指令。
- 函数代码:编译后的程序代码会存储在代码区,程序执行的时候就从这里读取指令。
可以通过下图直观查看