2021-11-06 C++程序内存模型-内存四区

2024-06-10 13:58

本文主要是介绍2021-11-06 C++程序内存模型-内存四区,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C++程序在执行时,将内存大方向划分为4个区域:

全局区,代码区,栈区,堆区

1. 代码区和全局区

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域(代码区和全局区

1.1 代码区

代码区:存放函数体的二进制代码,由操作系统进行管理
存放CPU执行的机器指令。
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。
代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

1.2 全局区

全局区:存放全局变量和静态变量以及常量
全局变量和静态变量存放在此
全局区还包含了常量区,字符串常量和其他常量也存放在此处
该区域的数据在程序结束后由操作系统释放

#include<iostream>
using namespace std;/*全局变量*/
int c = 10;
int d = 10;/*const修饰全局常量*/
const int g = 10;
const int h = 10;int main()
{/*全局区*//*静态变量  在普通变量前加static,属于静态变量*/static int e = 10;static int f = 10;/*创建普通局部变量*/int a = 10;int b = 10;/*const修饰局部常量*/const int s = 10;const int m = 10;/*常量 1.字符串常量 */cout << "字符串常量的地址为:" << (int)&"hello word" << endl;cout << endl;cout << "局部变量a的地址为:" << (int)&a << endl;cout << "局部变量b的地址为:" << (int)&b << endl;cout << endl;cout << "全局变量c的地址为:" << (int)&c << endl;cout << "全局变量d的地址为:" << (int)&d << endl;cout << endl;cout << "静态变量e的地址为:" << (int)&e << endl;cout << "静态变量f的地址为:" << (int)&f << endl;cout << endl;cout << "const修饰的全局常量g的地址为:" << (int)&g << endl;cout << "const修饰的全局常量h的地址为:" << (int)&h << endl;cout << endl;cout << "const修饰的局部常量s的地址为:" << (int)&s << endl;cout << "const修饰的局部常量m的地址为:" << (int)&m << endl;cout << endl;system("pause");return 0;
}

在这里插入图片描述

总结:

C++中在程序运行前分为全局区和代码区
代码区特点是共享和只读
全局区中存放全局变量,静态变量,常量
常量区中存放const修饰的全局常量和字符串常量

2. 栈区和堆区

2.1 栈区

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

#include<iostream>
using namespace std;/*
栈区数据的注意事项--不要返回局部变量地址
栈区的数据由编译器管理开辟和释放
*/
int * fun()
{int a = 10; //局部变量,存放在栈区,栈区的数据在函数执行完后自动释放return &a; //返回局部变量的地址
}int main()
{int * p = fun(); //接收fun函数的返回值cout << * p << endl;  //第一次可以打印正确的数字,因为编译器做了保留cout << * p << endl; //第二次这个数据就不再保留了,此块内存已被释放system("pause");return 0;
}

2.2 堆区

由程序员分配和释放,若程序员不释放,程序结束时由操作系统收回,C++中主要利用new在堆区开辟内存

#include<iostream>
using namespace std;/*
栈区数据的注意事项--不要返回局部变量地址
栈区的数据由编译器管理开辟和释放
*/
int * fun() //形参数据也会放在栈区
{//利用new关键字,可以将数据开辟到堆区//指针本质是局部变量 ,放在栈上。指针保存的数据放在堆区int* p = new int(10);return p;
}int main()
{//在堆区开辟数据int * p = fun(); //接收fun函数的返回值cout << * p << endl;  system("pause");return 0;
}

3. new操作符

C++中利用new操作符在堆区开辟数据,堆区开辟的数据,由程序员受到开辟,手动释放,释放利用操作符delete。
利用new创建的数据,会返回该数据对应的类型的指针。

#include<iostream>
using namespace std;/*new的基本语法*/
int* func()
{/*在堆区创建整形数据new返回的是该数据类型的指针*/int* p = new int(10);return p;
}void text01()
{int* p = func();cout << *p << endl;//堆区数据由程序员管理释放delete p; 
//	cout << *p << endl;   内存已经释放,再次访问就是非法操作,会报错
}void text02()
{/*创建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()
{//text01();text02();system("pause");return 0;
}

总结

不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程。

这篇关于2021-11-06 C++程序内存模型-内存四区的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048353

相关文章

C++迭代器失效的避坑指南

《C++迭代器失效的避坑指南》在C++中,迭代器(iterator)是一种类似指针的对象,用于遍历STL容器(如vector、list、map等),迭代器失效是指在对容器进行某些操作后... 目录1. 什么是迭代器失效?2. 哪些操作会导致迭代器失效?2.1 vector 的插入操作(push_back,

Java使用WebView实现桌面程序的技术指南

《Java使用WebView实现桌面程序的技术指南》在现代软件开发中,许多应用需要在桌面程序中嵌入Web页面,例如,你可能需要在Java桌面应用中嵌入一部分Web前端,或者加载一个HTML5界面以增强... 目录1、简述2、WebView 特点3、搭建 WebView 示例3.1 添加 JavaFX 依赖3

防止SpringBoot程序崩溃的几种方式汇总

《防止SpringBoot程序崩溃的几种方式汇总》本文总结了8种防止SpringBoot程序崩溃的方法,包括全局异常处理、try-catch、断路器、资源限制、监控、优雅停机、健康检查和数据库连接池配... 目录1. 全局异常处理2. 使用 try-catch 捕获异常3. 使用断路器4. 设置最大内存和线

使用Python创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

将Java程序打包成EXE文件的实现方式

《将Java程序打包成EXE文件的实现方式》:本文主要介绍将Java程序打包成EXE文件的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录如何将Java程序编程打包成EXE文件1.准备Java程序2.生成JAR包3.选择并安装打包工具4.配置Launch4

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指