c++笔记:内存分区模型

内存分区模型

c++程序在执行时,将内存划分为4个区域

  • 代码区:存放函数体二进制代码,由操作系统管理

  • 全局区:存放全局变量、静态变量及常量

  • 栈区:由编译器自动分配释放,存放函数参数值、局部变量等

  • 堆区:由程序员分配释放,若程序员不释放程序结束时由操作系统回收

内存四区意义:

不同区域存放的数据,赋予不同生存周期,编程会更灵活

1.程序运行前

在程序编译后,生成.exe可执行程序,未执行该程序前分为两个区域

代码区:

存放CPU执行的机器指令

代码区是共享的:对于频繁被执行的程序,只需要在内存中有一份代码即可

代码区是只读的:防止程序意外地修改了它的指令

全局区:

全局变量、静态变量(静态指在整个程序生命周期的地址静止不变)和常量存放于此

常量包含字符串常量和const修饰的全局变量

该区域数据在程序结束后由操作系统释放

#include<iostream>
#include<string>
using namespace std;

//全局变量
int g_a=10;
int g_b=10;

//const修饰全局变量(全局常量)
const int c_g_a=10;

int main(){
    
	//创建普通局部变量(凡是定义于函数内部均为局部变量)
	int a=10;
	int b=10;

	cout<<"局部变量a的地址为:"<<(int)&a<<endl;
	cout<<"局部变量b的地址为:"<<(int)&b<<endl;

	cout<<"全局变量g_a的地址为:"<<(int)&g_a<<endl;
	cout<<"全局变量g_b的地址为:"<<(int)&g_b<<endl;

	//静态变量
	static int s_a=10;
	static int s_b=10;
	cout<<"静态变量s_a的地址为:"<<(int)&s_a<<endl;
	cout<<"静态变量s_b的地址为:"<<(int)&s_b<<endl;

	//常量
	//字符串常量
	cout<<"字符串常量的地址为:"<<(int)&"Hello world!"<<endl;

	//const修饰的变量
	//const修饰全局变量
	cout<<"全局常量c_g_a的地址为:"<<(int)&c_g_a<<endl;

	//const修饰局部变量
	const int c_l_a=10;
    cout<<"局部常量c_l_a的地址为:"<<(int)&c_l_a<<endl;

	return 0;
}

运行结果:

2.程序运行后

栈区:

由编译器自动分配释放,存放函数参数值,局部变量等

Attention:不要返回局部变量地址,因为栈区开辟的数据由编译器自动释放

#include<iostream>
using namespace std;

int *func(int b){  //形参也存于栈区
	b=100;
	int a=10;  //局部变量,存于栈区
	return &a;  //返回局部变量地址(warning C4172: returning address of local variable or temporary)
}

int main(){
	//接收func()的返回值
    int *p=func(1);

	cout<<*p<<endl;  //第一次可打印正确数据是因为编译器做了保留
	cout<<*p<<endl;  //第二次该数据不再保留

	return 0;
}

运行结果:

堆区:

由程序员分配释放,若程序员不释放,程序结束时由操作系统回收

c++中利用 new 在堆区中开辟内存,利用 delete 释放

语法: new 数据类型

new返回值为其数据类型的指针,因此在堆区创建数据后还要定义一个相应的指针接收

#include<iostream>
using namespace std;

//1.new的基本语法
int *func(){
	//在堆区创建整型数据
	int *p=new int(10);  //new返回是该数据类型的指针
	return p;
}

void test01(){
	int *p_test01=func();
	cout<<*p_test01<<endl;
	cout<<*p_test01<<endl;

	cout<<(int)p_test01<<endl;
	int x=1;
	cout<<"x位于栈区的地址为:"<<(int)&x<<endl;

	delete p_test01;  //利用delete释放堆区数据
	cout<<*p_test01<<endl;  //内存已经释放,该句非法
}

//2.在堆区利用new开辟数组
void test02(){

	//在堆区创建10个整形数据数组
	int *arr=new int[10];
	for(int i=0;i<10;i++){
		*arr=100+i;

		cout<<"第"<<i<<"号数据为:"<<*arr<<endl;
		cout<<"第"<<i<<"号数据位于堆区的地址为:"<<(int)arr<<'\t'
			<<"arr位于栈区地址为:"<<(int)&arr<<endl;
		
		arr++;
	}
	delete[]arr;  //释放堆区数组时,要加[]
}

int main(){
	test01();
	test02();
	return 0;
}

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值