一.内存分区模型
c++程序执行时,将内存大致分为四个区域
- 代码区:存放函数的二进制代码,由操作系统进行管理(共享、只读)
- 全局区:存放全局变量,静态变量以及常量(结束后,有操作系统释放)
- 栈区:由编译器自动分配释放,存放函数的参数数值,局部变量等
- 堆区:由程序员分配和释放,若程序员结束时由操作系统回收
-
全局区:全局变量、静态变量、常量(字符串常量、const修饰的全局变量)
include<iostream> using namepase std; //全局变量 int q_a=10; int q_b=10; //const修饰的全局常量 const int c_q_a=10; const int c_q_a=10; int main() { //全局区 //全局变量、静态变量、常量 //创建普通局部变量 int a=10; int b=10; //这两个局部变量的地址相差不大,说明是储存在同一个区域内 cout <<"局部变量a的地址为:"<<(int)&a<<endl;// cout <<"局部变量b的地址为:"<<(int)&b<<endl;// //这两个全局变量和上边的局部变量相差比较大,说明局部变量和全局变量是储存在不同的区域 cout <<"局部变量q_a的地址为:"<<(int)&q_a<<endl;// cout <<"局部变量q_b的地址为:"<<(int)&q_b<<endl;// //静态变量 static int s_a=10; static int s_a=10; //静态变量和全局变量的值很近,是放在同一个区域内的,而和局部变量相差又比较大,是不同的区域 cout <<"局部变量s_a的地址为:"<<(int)&s_a<<endl;// cout <<"局部变量s_b的地址为:"<<(int)&s_b<<endl;// //常量 //字符串常量 cout<<"字符串常量的地址为:"<<(int)&("Hwllo World")<<endl; //const 修饰的常量 //const修饰的全局变量 cout<<"全局常量c_q_a的地址为:"<<(int)&c_q_a; cout<<"全局常量c_q_b的地址为:"<<(int)&c_q_b; //const修饰的局部变量 const int c_j_a=10; const int c_j_b=10; cout<<"局部常量c_j_a的地址为:"<<(int)&c_j_a; cout<<"局部常量c_j_b的地址为:"<<(int)&c_j_b; system("pause"); return 0; }
-
栈区:注意不要返回局部变量的地址,栈区的数据由编译器自动释放
include<iostream> using namepase std; int fun(int b)//形参数据会放在栈区 { int a=10;//局部变量存储在栈区,栈区数据在函数执行完后自动释放 return &a;//返回局部变量的地址 } int main() { int *p=fun(1);//接受fun函数的返回值 cout<<*p<<endl;//第一次可以打印正确的数值,是因为执行函数后释放的时候,编译器做了保留 cout<<*p<<endl;//第二次,这个数值不再被保留 system("pause"); return 0; }
3.堆区
include<iostream> using namepase std; int fun() { //利用new关键字,可以将数据开辟到堆区 int *p = new int (10);//指针本质是局部变量,放在栈上,指针保存的数据是放在堆区 return p; } int main() { int *p = func(); //因为指针指向的内容是放在堆区,由程序员来释放的,所以这里输出两次以上的数值,它依旧是正确的数值 cout << *P<<endl; cout << *P<<endl; cout << *P<<endl; cout << *P<<endl; system("pause"); return 0; }
4.new的操作符
- c++利用new开辟数据区
- 堆数据的开辟,由程序员开辟,手动释放,释放利用操作符delete
- 利用new创建的数据,会返回该数据对应的类型的指针
include<iostream>
using namepase std;
int fun()
{
//利用new关键字,可以将数据开辟到堆区,返回的是该类型的指针,所以要用指针去接受它
int *p = new int (10);//指针本质是局部变量,放在栈上,指针保存的数据是放在堆区
return p;
}
//new的基本操作
void test01()
{
int *p = func();
cout << *P<<endl;//堆区的数据由程序员开辟,由程序员释放
delete p;//要想释放,就用delete
cout <<*p<<endl;//现在已经被释放了,如果在去输出就是非法输出了,会报错
}
//在堆区里用new开辟数组
void test02()
{
//创建10整形的数组
int *arr = new int[10];
for (int i=0;i<10;i++)//给十个元素赋值
{
arr[i]=i+100;
}
for(int i=0;i<10;i++)
{
cout<<arr[i]<<endl;
}
//释放堆区数组的时候,要加[]才可以
delete[] arr;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}