C++内存分区总结
前言
内存分区主要包括静态储存区、栈区、堆区、代码区这四个区,本文主要根据这四个区进行总结。
一、静态储存区
1.静态存储区包括:常量区(静态常量区),全局区(全局变量区)和静态变量区(静态区)
2.静态储存区存放的是包括:全局变量、全局常量(const修饰)以及静态变量(static修饰)、字符串常量(“paulim”)
3.静态储存区的内存在整个程序运行完就已经释放了
4.注意:局部变量和const修饰的局部变量,这两个带有“局部”两个字的变量都是存放在栈区(后面会解释)
#include<iostream>
using namespace std;
int a = 23;//全局变量
const int c_a = 22;//全局常量
int main() {
static int s_a = 22;//静态变量,也就是说我在函数内定义的除非加static,或者是字符串常量,其他都是在栈区,运行完就释放了
int s_b = 65;//局部变量
const int c_b = 56;//const 修饰的局部常量
cout << "全局变量的地址为" << int(&a) << endl;
cout << "静态变量的地址为" << int(&s_a) << endl;
cout << "字符串常量的地址为" << char(&"paulim") << endl;
cout << "全局常量的地址为" << int(&c_a) << endl<<endl;
cout << "已下并不在全局区" << endl;
cout << "局部变量: " << int(&s_b) << endl;
cout << "const修饰的局部变量 " << int(&c_b) << endl;
system("pause");
}
二、栈区
1.堆栈区存放的是局部变量和const修饰的局部变量以及形参,形参是指
int func(int a, int b)//这里的a.b 就是形参
2.栈区内存在函数主体运行完就会自动释放
3.函数里面的局部变量是不可以返回的,准确来说,函数不能通过返回指向栈内存的指针,因为只要调用一次,指针所指向的内存空间就会释放,下一次调用时候,指针就不知道指向哪里了,这时候程序就会出错
#include<iostream>
using namespace std;
int* func() {//前面那个*跟返回相关,返回的是一个指针
int a = 50; //定义一个局部常量
int *p = &a;//取局部常量a的地址,拿一个指针p来接受他
return p;//返回一个指针
}
int main() {
int *p = func();//把func函数的返回值拿一个新的指针p来接收他
cout << *p << endl;//*p为解引用,第一次编译器保留,注意编译器还会保留一次
cout << *p << endl;//第二次打印内存已经释放了
system("pause");
}
三、堆区
1.堆区是个人用户开辟和释放赋内存区域,一般当需要定义大内存数组时,通常应该将其定义在堆区
2.堆区的开辟:
int *p=new int(10);
int *arr=net int[1000];//数组
3.堆区的释放:
delete p;
delete [] arr;//数组
3.堆区与栈区的区别在于,在堆区开辟的局部变量指针可以返回,多次调用不会乱码,它的地址不会像栈区开辟一样,函数结束后就自动释放。
#include<iostream>
using namespace std;
int* func() {
int *b = new int(10);//用new在堆区开辟空间,返回的是该数据类型的指针,如果是double,就用double的指针接收他。
//double *c=new double(20);
return b;//定义函数时候 int*,返回的是一个指针,返回直接写b,b就是指针
}
void test1() {
int *p = func();//定义一个指针接收他。
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;//连续打印不会出乱码,不像栈区
delete p;//delete后面跟的是指针
//cout << *p << endl;提示访问异常
}
void test2() {
int* arr=new int [10];//这里的10用中括号,代表的是数组长度
for (int i = 0; i < 10; i++) {
arr[i] = 100 + i;
}
for (int j = 0; j < 10; j++) {
cout << arr[j] << endl;//打印出来看看
}
delete [] arr;//释放内存数组要用到[]
}
int main() {
test1();//堆区开辟一个整形的数,然后释放他
test2();//堆区开辟一个数组空间,然后又释放它
system("pause");
}
四、代码区
1.代码区 :特点是共享和可读。共享的意思是可以打开很多个exe文件,使得程序能够在内存中独立于其他程序运行,可读指的是防止误编译。
总结
内存分区能够更好帮我们理解各个分区的作用,特别注意栈区和堆区的区别,1.栈区是函数运行完后内存自动释放,函数的局部变量指针不可以多次调用。2.堆区是由用户个人创建空间和释放的,函数的局部变量的指针可以多次调用。3.静态存储区的内存等到程序运行完才释放。