C++中内存分为四区,由内存地址从大到小依次为栈区、堆区、全局区和代码区。(网上各种版本也有五区的说法,主要区别在全局区,将全局区分为静态区和常量区)。

栈区

  • 栈区由系统管理–>方法调用时开辟空间,方法结束时回收空间。
  • 在内存中由高地址向低地址拓展,是一块连续的内存区域,遵循先进后出原则。
  • 栈区的内存空间是在运行时由系统进行分配。
  • 栈区存放:形参、局部变量。

堆区

  • 最大的特点是由程序员手动管理;
  • 堆区是从低地址向高地址拓展,内存空间不连续,以链表结构存在,遵循先进先出原则。
  • 开辟出的空间的首地址是在栈区,如int * p = new int[]{1,2},此时p位于栈区,而数组元素位于堆区。
  • 堆区存放由newmalloc等由程序员开辟的空间。
  • 堆区需要通过delete回收。

全局区

  • 存放全局变量和静态变量。
  • 内存空间由系统管理,程序启动时开辟,结束时回收,执行期间一直存在。

有另一种分法将全局区分为全局静态区和常量区,常量区存放常量(整型、字符型、浮点型和字符串),程序运行期间不能被改变,包括已初始化的全局变量和静态变量。

代码区

代码区中存放编译后的二进制代码,为不可寻址区。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

int global_num = 10;
const int global_num_c = 10;
static int global_num_s = 10;

int main()
{
int local_num = 10;
static int local_num_s = 10;
const int local_num_c = 10;

int *p = new int[2]{1, 2};

cout << "全局变量:" << &global_num << endl;
cout << "const修饰的全局变量:" << &global_num_c << endl;
cout << "全局静态变量:" << &global_num_s << endl;
cout << endl;
cout << "局部变量:" << &local_num << endl;
cout << "局部静态变量:" << &local_num_s << endl;
cout << "const修饰的局部变量:" << &local_num_c << endl;
cout << endl;
cout << "开辟空间的首地址:" << &p << endl;
cout << "开辟空间:" << &p[1] << endl;
}

四区

由上图可知局部变量位于栈区、全局变量和静态变量位于全局区,new开辟的空间位于堆区。

内存泄露与内存溢出

内存泄漏是指申请的内存空间使用完毕后未回收;内存溢出是指程序在申请内存时没有足够的内存空间供其使用。

https://www.jianshu.com/p/a3e80cb5198b