程序在运行的过程中是会被加载到内存中的,一个程序可能会存在不同的功能块,所以不同区域存放的数据,赋予不同的生命周期, 给我们更大的灵活编程
C++的程序会在内存中分为四大块:
代码区:存放函数体的二进制代码,由操作系统进行管理的
全局区:存放全局变量和静态变量以及常量
栈区:由编译器自动分配释放, 存放函数的参数值,局部变量等
堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
代码区
程序编译后是一个二进制的文件,这个二进制的文件便会放在代码区中。
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令
全局区
全局变量、静态变量、字符串常量和const修饰的全局常量存放在此.
该区域的数据在程序结束后由操作系统释放
栈区
局部变量,const修饰的局部常量都会分配到栈区中。
由系统自动管理释放
一个函数执行完之后,都会把在这个函数中创建的形参(本质也是一个局部变量)或者局部变量进行退栈操作,也就是销毁。销毁后的值是没有意义的。所以不能在一个函数中返回一个形参的地址,这是相当危险的操作。
如下程序:
int* test()
{
int i = 10; //在函数中创建的局部变量
return &i; // 返回i的地址
}
int main()
{
int* p = test();
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
return 0;
}
结果:
10
1515108752
1515108752
结果只有第一次正确,这是因为编译器暂时保留了一会,等到第二次去取值时就错了。
堆区
那么,上面的问题中,我们要怎么在函数中创建变量,并且还不会在函数运行结束后就被销毁呢?
解决方案其实也很优雅,就是另外开辟一个堆区,将用户自己创建的变量都放到这个区中,然后用户自行删除或者等到程序结束时自动销毁。
主要是用new来开辟的内存空间的。
用delete来释放
int* test()
{
int* i = new int(10); // 在堆中开辟新的空间
return i; // 返回i
}
int main()
{
int* p = test();
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
return 0;
}
结果:
10
10
10
总结:
堆区数据由程序员管理开辟和释放
堆区数据利用new关键字进行开辟内存
用delete来释放