目录
一、内存四区分别是
代码区、全局区、堆区和栈区,他们的作用各不相同,出现的时间也小有区别。
C++程序的运行分为两个阶段:编译和运行,大多数的东西其实是在编译期就已经确定了的,就比如函数和各种宏定义
二、程序运行前(编译期)出现的两个区域
1.代码区
代码区将我们所编写的代码转换为计算机所能理解的二进制代码储存在代码区中,这个区域由操作系统进行处理,并且具有只读和共享的特点。代码区更多的时候叫做代码段。
2.全局区
全局区用来存放我们所写的全局变量、静态变量以及常量(静态变量是用static修饰的在函数内的局部变量,它在被修饰后不会像一般的局部变量那样在函数结束时就被销毁,而会一直保留知道程序结束)。它也叫全局段。
三、程序运行时新出现的区域
1.栈区
栈区被用来存放程序在运行过程中产生的局部变量和函数的参数值等,栈区不能人为的控制,只能由编译器自动的分配和释放,这一点与堆区不一样,堆区将在下面阐述。正是因为局部变量是放在栈区的,但是由于栈区在函数结束后其所占用的内存会自动的被编译器释放,因此我们不能返回一个局部变量的地址 。
#include<iostream>
using namespace std;
int* temp() {
int a = 10;
int *b = &a;
cout << *b << endl;
return b;
}
int main() {
int* a = temp();
cout << *a << endl;
cout << *a << endl;
}
输出这一串代码,我们可以发现第一次打印的*a的结果与*b是一致的,但是第二次打印*a的时候结果却不一样了,这是因为编译器在释放该函数的内存后会将栈区中的局部变量进行 一次保留,但是这个保留只有一次,当我们调用了一次后,我们就没法再次进行调用了,这就是第二次*a的结果不同于第一次的原因。
2.堆区
堆区跟栈区最主要的不同点就是它的分配和释放是由人主动操控的,我们可以用关键字new在堆区中创建一个可供我们调用的内存区,而用delete去释放它,如果我们没有主动释放,则这个内存会在程序结束的时候自动释放。
//new返回的是一个指针,所以要用一个指针去接收它
//创建一个int型的变量
int* p = new int(10);
//创建一个int型的大小为10的数组
int* p = new int[10];
虽然它在程序结束的时候会自动释放,但是由于我们在程序运行时没有释放,这块内存始终被占用了,即使我们没有使用它,这就会导致内存泄漏。这可能会导致未定义的问题,因此我们还是需要将它进行手动释放。
因为我们常常会忘记释放它,因此new和delete还是少用好,使用智能指针让程序帮我们管理内存会更安全一些。关于智能指针的内容可以看我的新文章:重学C++11。