这是我在学习这方面知识的笔记,主要是网课上老师讲的内容和一些自己的想法,整理了一下,希望对学习这方面知识的小伙伴有帮助:)
1.内存条
全局区:
全局变量
静态变量 (static关键字)
常量:
字符串常量
const修饰的全局变量(全局常量)
非全局区:
局部变量
const修饰的局部变量(局部常量)
小知识:
g---global c----const l----local
这是一种书写习惯,没有其他特殊的作用,优点在于有助于区分数据的性质
如:
c_l_a=10 //意思是这个数据在这个代码中设置的是一个局部常量
代码:
#include<iostream>
using namespace std;
//全局变量
int g_a=10;
int g_b=10;
//const修饰的全局变量,全局常量
const int c_g_a=10;
const int c_g_b=10;
int main(){
//全局区
//全局变量 静态变量 常量
//创建普通局部变量
int a=10;
int b=10;
cout<<"局部变量a的地址为:"<<(int)&a<<endl;
cout<<"局部变量b的地址为:"<<(int)&b<<endl; //结果变量不在全局区
cout<<"全局变量a的地址为:"<<(int)&g_a<<endl;
cout<<"全局变量b的地址为:"<<(int)&g_b<<endl;
//可以理解为全局区和局部区在内存条中为两个独立的存储区域
//静态变量 在普通变量前加上关键字static,属于静态变量
static int s_a=10;
static int s_b=10;
cout<<"静态变量s_a的地址为:"<<(int)&s_a<<endl;
cout<<"静态变量s_a的地址为:"<<(int)&s_a<<endl;
//从运行结果上来看 全局变量和静态变量地址相近 因此可以看出两个区域在内存条中离得很近
//都在全局区中
//常量
//字符串常量
cout<<"字符串的地址为:"<<(int)&"hello world"<<endl;
//const修饰的变量
//const修饰的全局变量,const修饰的局部变量
cout<<"全局常量c_g_a的地址为:"<<(int)&c_g_a<<endl;
cout<<"全局常量c_g_b的地址为:"<<(int)&c_g_b<<endl;
const int c_l_a=10;
const int c_l_b=10;
cout<<"局部常量c_l_a的地址为:"<<(int)&c_l_a<<endl;
cout<<"局部常量c_l_b的地址为:"<<(int)&c_l_b<<endl;
system("pause");
return 0;
}
运行结果:
由代码运行结果可以非常直观的看到 不同数据类型在内存条上的分配
总结:
C++中代码存放区域分为全局区和代码区
代码区特点是共享和只读
全局区中存放全局变量 静态变量 常量
常量区中存放const修饰的全局常量和字符串常量
2.栈区
栈区是由编译器自动分配释放,存放函数的参数值,局部变量等
注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放(因此个人认为如何在栈区保留所需要的数据成了一个很重要的问题)
(这涉及到函数值的传递问题 有兴趣可以去了解一下三种值传递的方式)
如果返回局部变量的地址:
#include<iostream>
using namespace std;
int* func(int b)//形参数据也会放在栈区
{
int a = 10;//局部变量 放在栈区 栈区的数据执行完后自动释放
return &a; //返回局部变量的地址
}
int main() {
int* p = func(100);//接受返回值
cout << *p << endl;//第一次可以打印正确数字,是因为编译器做了保留
cout << *p << endl;//第二次这个数据就不再保留
system("pause");
return 0;
}
结果是第一得到数据10,
第二次出错
总体来说,栈区的数据地址传不出去,即在栈区创建的局部变量若无区域外的一个空间来存放那么会导致数据du
3.堆区
由程序员分配释放,若程序员不释放,程序结束时由系统回收
堆区内存主要由new来开辟
代码:
#include<iostream>
using namespace std;
int* func()
{
//利用new关键字可以将数据开辟到堆区
//指针本质也是局部变量,放在栈上,指针保存的数据是放在堆区
int * p = new int(10);//用指针去接收返回的地址编号
return p;//也就是说p这个指针本身是在栈上,但我们临时借用他在堆上返回了一个数据
}
//即它所指向的是堆区,即使系统收回它太身,但在堆区上的数据不变
//由此做到了间接性在堆区存放栈区数据,并返回(p的工作:将栈区数据复制到堆区)
int main(){
//在堆区开辟数据
int *p =func();
cout<<*p<<endl;
cout<<*p<<endl;
cout<<*p<<endl;
system("pause");
return 0;
}
画个图更直观
友友们,因为我也是个新人,如果有什么错误或不足请在评论区指出!!!
谢谢!!
❀❀❀❀❀
标签:栈区,10,常量,分块,int,堆区,局部变量,内存 From: https://blog.csdn.net/FairyFeather/article/details/137406160