C++中内存分为四区,由内存地址从大到小依次为栈区、堆区、全局区和代码区。(网上各种版本也有五区的说法,主要区别在全局区,将全局区分为静态区和常量区)。
栈区
- 栈区由系统管理–>方法调用时开辟空间,方法结束时回收空间。
- 在内存中由高地址向低地址拓展,是一块连续的内存区域,遵循先进后出原则。
- 栈区的内存空间是在运行时由系统进行分配。
- 栈区存放:形参、局部变量。
堆区
- 最大的特点是由程序员手动管理;
- 堆区是从低地址向高地址拓展,内存空间不连续,以链表结构存在,遵循先进先出原则。
- 开辟出的空间的首地址是在栈区,如
int * p = new int[]{1,2}
,此时p位于栈区,而数组元素位于堆区。
- 堆区存放由
new
、malloc
等由程序员开辟的空间。
- 堆区需要通过
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