阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量。文章设置为仅粉丝可见,是因为写博客确实花了不少精力。希望互相进步谢谢!!
提示:以下是本篇文章正文内容
一、内存四区的总结:
内存四区:代码区、全局区、栈区、堆区
程序执行前,生成代码区、全局区;程序执行后,生成栈区、堆区。
1、代码区:
存放CPU的机器指令(即代码的二进制形式)。具有两个特性:共享性和只读性
2、全局区:
全局区的数据在程序结束后才释放。
存放了1、全局变量(函数体外定义的变量) 2、静态变量 (static修饰的变量)3、字符串常量(string类型的常量) + 全局常量(const修饰的全局变量)。**但局部变量和局部常量都不在全局区。 **!!!!!!这里注意常量包括:字符串常量(string类型的常量,例如输出个“hello world”) + 全局常量(const修饰的全局变量) + 局部常量(const修饰的局部变量)。
下面代码是对于局部变量、全局变量、静态变量、字符串常量、全局常量、局部常量地址的一个输出,可以观察到全局变量、静态变量、字符串常量、全局常量是在同一段地址,即全局区;而局部变量、局部常量是在另外的同一段地址,即非全局区。
//全局区:全局变量(即函数体外的变量)、静态变量(static修饰的变量)、常量(字符串常量和全局常量【即const修饰的全局变量】)
//不在全局区:局部变量(即函数体内的变量)、局部常量(即const修饰的局部变量)
#include <iostream>
using namespace std;
//创建全局变量
int g_a = 10;
int g_b = 20;
//创建const修饰的全局变量(即全局常量)
const int c_g_a = 10;
const int c_g_b = 20;
int main() {
//创建局部变量
int a = 10;
int b = 20;
cout << "局部变量a的地址为:" << (int)&a << endl;
cout << "局部变量b的地址为:" << (int)&b << endl;
cout << "全局变量g_a的地址为:" << (int)&g_a << endl;
cout << "全局变量g_b的地址为:" << (int)&g_b << endl;
//创建静态变量
static int s_a = 10;
static int s_b = 20;
cout << "静态变量s_a的地址为:" << (int)&s_a << endl;
cout << "静态变量s_b的地址为:" << (int)&s_a << endl;
//常量
//字符串常量
cout << "字符串常量的地址为:" << (int)&"hello world" << endl;
//const修饰的变量(即const常量),包含如下:
//const修饰的全局变量(即全局常量)
//const修饰的局部变量(即局部常量)
cout << "const修饰的全局变量(即全局常量)的地址为:" << (int)&c_g_a << endl;
cout << "const修饰的全局变量(即全局常量)的地址为:" << (int)&c_g_b << endl;
//创建const修饰的局部变量(即局部常量)
const int c_l_a = 10;
const int c_l_b = 20;
cout << "const修饰的局部变量(即局部常量)的地址为:" << (int)&c_l_a << endl;
cout << "const修饰的局部变量(即局部常量)的地址为:" << (int)&c_l_b << endl;
system("pause");
return 0;
}
3、栈区
由编译器自动分配和释放。存放了**函数的参数值、局部变量(函数体内的变量)**等。
注意事项:不要返回局部变量地址。例如有时候想接收局部变量地址,利用指针再输出局部变量值,这时候不会正常输出,因为编译器在执行完函数后就会自动释放局部变量了。下面代码就是对注意事项的解释,可以看看。
//栈区:存放局部变量、函数的参数值等,由编译器自动分配释放
//注意事项:不要返回局部的变量地址 下面代码就是对注意事项的说明
#include <iostream>
using namespace std;
int* func() {
int a = 10;//局部变量,存放在栈区,函数结束后自动释放
return &a;//此处返回了局部变量的地址
}
int main() {
int* p = func();
//此处实际想两次通过调用函数,返回得到的局部变量地址,实现输出
cout << *p << endl; //第一次能成功输出10,因为编译器进行了保留
cout << *p << endl; //第二次不能成功输出10,因为编译器不再保留局部变量值
system("pause");
return 0;
}
4、堆区
由程序员分配和释放,若程序员未释放,程序结束时(也就是把exe关掉以后)由操作系统自动回收。c++中主要用new开辟堆区内存,delete释放堆区内存。
下面代码是对于堆区的一个说明,代码跟上面栈区代码很像,也是返回接收了个局部变量地址,但此时用指针就可以正确输出局部变量值,因为程序员并未去释放。重点就是(3)与(4)代码的对比。
//栈区:由程序员分配和释放。若程序员未释放,程序结束时由操作系统自动回收
//c++中主要用new开辟堆区
#include <iostream>
using namespace std;
int * func() {
int * p = new int(10);//利用new把10这个量存放至堆区,再用一个指针去接收这个地址
return p;
}
int main() {
int * p = func();
//三次都能成功输出10,因为程序员并未去释放
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}
若有错误,还望指正哈。
码字不易,谢谢点赞!!!
码字不易,谢谢点赞!!!
码字不易,谢谢点赞!!!