c++内存分区模型

2023-11-02

程序在运行的过程中是会被加载到内存中的,一个程序可能会执行可能会存在不同的功能块,所以不同区域存放的数据,赋予不同的生命周期, 给我们更大的灵活编程

C++的程序会在内存中分为四大块:

  • 代码区:存放函数体的二进制代码,由操作系统进行管理的
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:由编译器自动分配释放, 存放函数的参数值,局部变量等
  • 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

代码区

程序编译后是一个二进制的文件,这个二进制的文件便会放在代码区中。

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

代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令


全局区

  • 全局变量和静态变量存放在此.
  • 全局区还包含了常量区, 字符串常量和其他常量也存放在此.
  • 该区域的数据在程序结束后由操作系统释放.
  • C++中在程序运行前分为全局区和代码区
  • 代码区特点是共享和只读
  • 全局区中存放全局变量、静态变量、常量
  • 常量区中存放 const修饰的全局常量 和 字符串常量,局部变量和局部常量是另外一个内存块的栈的。

大概了解下是怎么回事就行,可以定义不同的变量去观察它们所在的地址块是否连续在一起来判断。


栈区

局部变量,局部常量都会分配到栈区中。

在函数中,实参传递给形参的过程是先在栈区为形参开辟一块内存块,然后将实参的值写入形参所在的内存块。这就是为什么需要修改一个实参的数时需要传递指针或者引用(引用其实也是一个指针)。通过指针的地址再去改变相应的值。

一个函数执行完之后,都会把在这个函数中创建的形参(本质也是一个局部变量)或者局部变量进行退栈操作,也就是销毁。销毁后的值是没有意义的。所以不能在一个函数中返回一个形参的地址,这是相当危险的操作。
如下程序:

int* test() {
	int i = 10; //在函数中创建的局部变量
	return &i; // 返回i的地址
}

int main() {
	int* p = test();
	cout << *p << endl;
	cout << *p << endl;
	cout << *p << endl;
	return 0;
}

结果:

10
1515108752
1515108752

结果只有第一次正确,这是因为编译器暂时保留了一会,等到第二次去取值时就错了。


堆区

那么,上面的问题中,我们要怎么在函数中创建变量,并且还不会在函数运行结束后就被销毁呢?
解决方案其实也很优雅,就是另外开辟一个堆区,将用户自己创建的变量都放到这个区中,然后用户自行删除或者等到程序结束时自动销毁。
主要是用new来开辟的内存空间的。

int* test() {
	int* i = new int(10); // 在堆中开辟新的空间
	return i; // 返回i
}

int main() {
	int* p = test();
	cout << *p << endl;
	cout << *p << endl;
	cout << *p << endl;
	return 0;
}

结果:

10
10
10

总结:

堆区数据由程序员管理开辟和释放

堆区数据利用new关键字进行开辟内存


本文主要参考:黑马程序员匠心之作|C++教程从0到1入门编程


更多精彩内容请关注我微信公众号:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++内存分区模型 的相关文章

  • Qt - QProcess 不工作

    我尝试启动 Internet Explorer 所以我使用下面的代码 QProcess process new QProcess this QString temp C Program Files Internet Explorer iex
  • Exit() 时是否调用基本对象析构函数?

    我意识到这个问题已经出现过几次 但我试图获得上述问题的明确答案 但我不断遇到相互矛盾的信息 我需要知道的是 当我使用 exit 时 基本类对象是否被破坏 我知道需要删除动态内存 但我的意思更像是 include
  • 循环遍历 C 结构中的元素以提取单个元素的值和数据类型

    我有一个要求 我有一个 C 语言的大结构 由大约 30 多个不同数据类型的不同元素组成 typedef struct type1 element1 type2 element2 type3 element3 type2 element4 1
  • 有些有助于理解“产量”

    在我不断追求少吸的过程中 我试图理解 产量 的说法 但我不断遇到同样的错误 someMethod 的主体不能是迭代器块 因为 System Collections Generic List 不是迭代器接口类型 这是我被卡住的代码 forea
  • cpp.react库的C++源代码中奇怪的“->* []”表达式

    这是我在文档中找到的 C 片段cpp react 库 https github com schlangster cpp react implicit parallelism auto in D MakeVar 0 auto op1 in g
  • 不同 C++ 文件中的相同类名

    如果两个 C 文件具有相同名称的类的不同定义 那么当它们被编译和链接时 即使没有警告也会抛出一些东西 例如 a cc class Student public std string foo return A void foo a Stude
  • 获取没有显式特征的整数模板参数的有符号/无符号变体

    我希望定义一个模板类 其模板参数始终是整数类型 该类将包含两个成员 其中之一是类型T 另一个作为类型的无符号变体T 即如果T int then T Unsigned unsigned int 我的第一直觉是这样做 template
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 如何使用 x64 运行 cl?

    我遇到了和这里同样的问题致命错误 C1034 windows h 未设置包含路径 https stackoverflow com questions 931652 fatal error c1034 windows h no include
  • 已发布的 .Net Core 应用程序警告安装 .Net Core,但它已安装

    我制作了一个 WPF 和控制台应用程序 供某人在我无法访问的私人服务器上使用 我使用 Visual Studio 2019 的内置 发布向导 来创建依赖于框架的单文件应用程序 当该人打开 WPF 应用程序时 他们会看到标准警告 他们单击 是
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • memcpy/memmove 到联合成员,这是否设置“活动”成员?

    重要说明 一些评论者似乎认为我是从工会抄袭的 仔细看memcpy 它从普通旧地址复制uint32 t 它不包含在联合中 另外 我正在复制 通过memcpy 到工会的特定成员 u a16 or u x in a union 不直接到整个联盟本
  • 如何在 C# 中创建异步方法?

    我读过的每一篇博客文章都会告诉您如何在 C 中使用异步方法 但由于某些奇怪的原因 从未解释如何构建您自己的异步方法来使用 所以我现在有这段代码使用我的方法 private async void button1 Click object se
  • C++:为什么 numeric_limits 对它不知道的类型起作用?

    我创建了自己的类型 没有任何比较器 也没有专门化std numeric limits 尽管如此 由于某种原因 std numeric limits
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • WPF DataGrid / ListView 绑定到数组 mvvm

    我们假设你有 N 个整数的数组 表示行数的整数值 在模型中 该整数绑定到视图中的 ComboBox Q1 如何将数组 或数组的各个项目 绑定到 DataGrid 或 ListView 控件 以便 当您更改 ComboBox 值时 只有那么多
  • 代码中的.net Access Forms身份验证“超时”值

    我正在向我的应用程序添加注销过期警报 并希望从我的代码访问我的 web config 表单身份验证 超时 值 我有什么办法可以做到这一点吗 我认为您可以从 FormsAuthentication 静态类方法中读取它 这比直接读取 web c
  • 在 System.Type 上使用条件断点时出错

    这是函数 public void Init System Type Type this Type Type BuildFieldAttributes BuildDataColumns FieldAttributes 我在第一行设置了一个断点
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names

随机推荐

  • 提升企业网络安全的重要性:EventLog Analyzer的角色

    在今天的数字时代 企业对网络安全的需求愈发迫切 随着互联网的不断发展和企业信息的数字化 网络攻击的威胁也不断增加 为了保护企业数据和系统的完整性 网络安全已经成为每个企业都必须认真对待的重要问题 在这个背景下 我们不得不提到一种强大的工具
  • SSM+mysql课程题库管理系统-计算机毕业设计源码18655

    摘 要 随着科学技术的飞速发展 各行各业都在努力与现代先进技术接轨 通过科技手段提高自身的优势 对于课程题库管理系统当然也不能排除在外 随着网络技术的不断成熟 带动了课程题库管理系统 它彻底改变了过去传统的管理方式 不仅使服务管理难度变低了
  • ENVI_IDL: 基础语法详解

    01 题目 02 代码说明 题目本身很简单 但是我自己加了一些东西进去增加难度 主要包括print函数的封装 格式化字符串 但是不影响代码的阅读 注 对于没有语言基础的人而言相对阅读困难 但是由于IDL是解释型语言 类似于Python 所以
  • 【PyTorch】如何取得预训练模型的标签label列表(以 Alexnet 在 ImageNet 上的预训练模型为例)

    PyTorch 预训练模型 PyTorch 提供过了大量的预训练模型可以直接拿来使用 或者进行增量训练和微调 拿 Alexnet 的预训练模型为例 import torch import torchvision model torchvis
  • Ubuntu系统下 .7z 文件压缩解压命令

    安装软件 sudo apt install p7zip full 解压文件 解压命令 7z x filename 7z r o test 参数说明 7z 解压缩文件命令 x 表示解压缩 r 表示递归解压缩所有的子文件夹 o 指定解压到的那个
  • JProfile 分析OOM hprof文件

    JProfile 分析OOM OutOfMemoryError 1 JVM组成 首先要明白JVM组成 方法区 非堆 Method Area No Heap Java栈 虚拟机栈 VM Stack Java Stack 本地方法栈 Nativ
  • 解决浏览器”您的连接不是私密链接“的问题!最详细!!!

    Google的Chorom浏览器打开baidu主页 显示 您的连接不是私密连接 攻击者可能会试图从 x x x x 窃取您的信息 例如 密码 通讯内容或信用卡信息 了解详情 NET ERR CERT INVALID 网上找了很多人的解决办法
  • LeetCode 465. Optimal Account Balancing

    原题网址 https leetcode com problems optimal account balancing A group of friends went on holiday and sometimes lent each ot
  • linux ftp查看用户目录权限,linux 指定ftp用户 特定目录及权限

    Linux添加FTP用户并设置权限 在linux中添加ftp用户 并设置相应的权限 操作步骤如下 1 环境 ftp为vsftp 被限制用户名为test 被限制路径为 home test 2 建用户 在root用户下 useradd d ho
  • MyBatis-Plus——代码自动生成器

    哈喽 大家好 我是 一位上进心十足的 Java领域博主 的写作风格 喜欢用 通俗易懂 的文笔去讲解每一个知识点 而不喜欢用 高大上 的官方陈述 博客的领域是 面向后端技术 的学习 未来会持续更新更多的 后端技术 以及 学习心得 如果有对 后
  • Cesium中文教程-Cesium Workshop(一)

    欢迎来到Cesium社区 非常高兴能加入我们 为了帮助您开发自己的web地图应用程序 本教程将从头到尾介绍如何开发一款简单但有广泛影响的Cesium应用程序 本教程将接触到许多CesiumJS API重要的方面 但这并不意味着包括所有 Ce
  • openLDAP安装卸载与重装

    安装卸载 安装与卸载点击跳转 openLDAP与phpldapadmin安装点击跳转 重装问题 点击跳转
  • 基于SpringBoot工程开发Docker化微服务

    目录 1 微服务容器化治理的优缺点 1 1 微服务容器化的优点 1 2 微服务容器化的缺点 2 微服务的两种模式 2 1 Microservice SDK 2 2 ServiceMesh 3 微服务容器化治理的推荐模式 4 Windows下
  • 湖南省副省长秦国文一行调研考察亚信科技

    9月5日 湖南省人民政府党组成员 副省长秦国文一行到亚信科技调研考察 亚信科技高级副总裁陈武主持接待 图 双方合影 在亚信科技创新展示中心 秦国文了解了亚信科技在5G 算力网络 人工智能 大数据等前沿领域的创新探索 在数字化运营 智慧城市
  • 使用java API操作hdfs--读取hdfs文件并打印

    在myclass之中创建类文件 这个myclass目录是自己创建的 编译的时候会报如下的错误 很明显就是没有导入包的结果 见这个API网站 则可以找到响应的包 当然还有java的api文档 http hadoop apache org do
  • Java程序Png图片保持透明度处理

    核心代码 import javax imageio ImageIO import java awt import java awt image BufferedImage import java io File import java io
  • Springboot调整接口响应返回时长(解决响应超时问题)

    Springboot调整接口 会话响应返回时长 解决响应超时问题 配置Http会话超时 可以通过两种方式为Spring Boot应用程序配置HTTP会话超时 application properties中配置会话超时 最简单的方法是在你的a
  • 在互联网上,没有人知道你是一条狗?

    1993 年 纽约客 The New Yorker 杂志刊登一则由彼得 施泰纳 Peter Steiner 创作的漫画 标题是 On the Internet nobody knows you re a dog 这则漫画中有两只狗 一只黑狗
  • 【C语言】通讯录实现以及信息保存至文件。

    实现一个通讯录 通讯录用来存放1000个人的信息 每个人的信息包括 姓名 性别 年龄 电话 住址 提供方法 1 添加联系人信息 2 删除指定联系人信息 3 查找指定联系人的信息 4 修改指定联系人信息 5 显示所有联系人信息 6 清空所有联
  • c++内存分区模型

    程序在运行的过程中是会被加载到内存中的 一个程序可能会执行可能会存在不同的功能块 所以不同区域存放的数据 赋予不同的生命周期 给我们更大的灵活编程 C 的程序会在内存中分为四大块 代码区 存放函数体的二进制代码 由操作系统进行管理的 全局区