一、概述
在C++程序中,一般会将程序的内容按类型分别储存在四个区域内。这四个区域分别是:全局数据区、代码区、堆区和栈区.
各区域储存的数据类型和特点:
全局数据区:由操作系统进行管理,用于存放全局变量、全局常量、字符串常量以及静态变量。
代码区:由操作系统进行管理,用于存放各种函数体的二进制代码。
栈区:由编译器负责分配和清理,用于存放函数体内部的局部变量和函数的参数。
堆区:由程序员负责分配和回收,若程序员不释放,则在程序结束后有操作系统负责回收。
二、在程序运行前就已分配的区域
1.代码区:
特点:存放CPU执行的机器指令
1°数据共享:当一个程序可能被频繁使用时,比如同一个exe文件被单击多次运行多个实例时,这多个实例只共享一份代码。
2°只读:代码区的数据是只读不可写的,原因是防止程序发生故障时意外修改了程序代码。
2.全局区:
特点;用于存放全局变量、全局常量、字符串常量、static静态变量。
注:C++中,常量分为字符串常量和被const修饰的变量。而被const修饰的变量又可细分为两种:一种是const修饰的全局变量,又称全局常量。它们被存储在全局区中;另一种是const修饰的局部变量,他们被存储在栈区中。
三、在程序运行后才分配的区域
3.栈区:
我们看以下示例:
int* test(){//返回int类型的指针
int a=10;
int*p=&a;//指针存放在栈区,局部变量数值也存放在栈区
return p;}//当函数运行完毕后 int a=10作为一个存放在栈区的局部变量便被清空。
int main(){
int *q=test();
cout<<*q<<endl;//将指针进行解引用输出。此时第一次调用仍输出成功的原因是编译器暂时保留了值
cout<<*q<<endl; //第二次不再保留数据
}
运行结果:10 267955168//乱码
综上也可以进一步解释为什么函数参数,返回值的值传递为什么传不出去。因此不要返回栈区的数据或地址。
4.堆区
C++中可以用new关键字来将一个数据存放在堆区中
示例:
int *fanc()
{
int*p=new int (10);//此时指针指向的值是10,且int后面不写变量名。
return p;}
int main()
{
int *q=fanc();
cout<<*q<<endl;
cout<<*q<<endl;
cout<<*q<<endl;}
运行结果:10 10 10
实际上,指针p作为一个局部变量仍然储存在栈区,但是指针p指向的变量int(10)却是存在了堆区里