(C++) 详解内存地址空间

详解内存空间

0. 概述

一个C/C++ 程序,编译之后,形成的程序,在执行期间,内存中不仅存在一块区域用于存放代码,还有一些其他的区域用于使用,本节会详解C/C++内部所使用的内存地址空间,关于各内存的作用、位置做一个整体概述。

1. C++ 内存布局

操作系统的内存布局可大致分为两块:内核态和用户态,此处的内核态和用户态,不同于操作系统在执行时所进入的内核态和用户态,此处专指内存。二者有类似之处,例如:只有操作系统处于内核态时才可以访问内核态内存,因此二者容易产生混淆。

仅需了解,此处指代:内存内核态 和 内存用户态。

内存内核态暂且不去深究,内存用户态在C++程序执行时,会划分成以下内容:

【栈、堆、全局/静态区、文字常量区、程序代码区】(地址从高到低)

2. 内存分区

在这里插入图片描述

3. 栈区

栈:用于存放局部变量、函数参数、函数调用返回值、函数调用返回地址等数据,程序从main 主函数开始运行,到主函数运行结束,在此之间调用其他函数,可看作将其他函数进行压栈的一个过程,在栈区内的变量、地址等,当该函数执行结束后,其中的资源由系统自动释放。如main 函数中调用 func 函数,func 函数内生成一个数据,将其作为返回值进行返回。main 函数中使用变量进行接收,打印,可以看出打印值不同于 func 函数中的值(未定义行为),当func 返回后,该函数出栈,其中的资源被系统释放。

示例如下:

char *func() {char buf[] = "hello world";return buf;
}
int main(int argc, char *argv[]) {char *buf = func();cout << "buf = " << buf << endl;return 0;
}

另外值得注意的一点是,栈区的使用,操作方式类似于数据结构中的栈,即在使用时,后进先出,函数调用机制使用栈区完成,大量频繁的调用栈区,务必会造成时间资源的消耗,导致程序的执行效率下降。C 语言解决方法是使用宏代替短小频繁的函数体,C++ 语言的解决方法是使用内联函数进行替换,还需提高编程技巧。

机器在栈上申请的空间有限,因此在栈上使用的内存需要注意大小。

4. 堆区

堆位于栈区下,全局/静态区上,栈区向下生长,堆区向上生长,因此日常提到堆栈,是因为这两者的内存空间十分接近。

堆区是程序员可手动分配的内存空间,特点是需要手动申请和手动释放,在C语言中使用 malloc 和 free 进行申请和释放。C++中则使用 new 和 delete 进行申请和释放,此处不再赘述 malloc/free 和 new/delete 的区别,若感兴趣请自行查询相关资料。

堆区申请的数据在程序执行阶段不会被系统所自动释放,因此C和C++程序员需要注意内存大小,内存释放问题。(程序结束时会被操作系统回收)

需要注意:

1.申请堆内存之后,立刻验证内存空间是否申请成功。

2.申请行为必须对应释放行为,有申请内存,则必有释放行为,因此写 malloc 之后立刻写上free语句。new/delete 同理。

3.free 和 delete 虽然传入的是指针,但释放的确是内存空间,因此需要将该指针置为null,防止野指针问题。

另外,堆的运行速度、效率不及栈,且存在内存碎片问题。 使用 malloc 和 free 时,需要添加头文件。

5. 全局/静态区

全局区、静态区是一片区域,原因在于全局变量和静态变量的内存地址都位于这片空间下。该空间位于堆下,低地址。

定义一个变量时,需要及时进行初始化,变量被定义 static 之后,只有当前模块可见。当一个局部变量被定义为 static时,虽然该局部变量的可见范围仍然属于该函数,但该局部变量的生命周期已经延长到了程序生存期。

6. 文字常量区(只读)

文字常量区用于定义常量字符串,程序结束后由系统进行释放,不可进行写操作。

const char* 定义文字常量后,直接使用字符串,二者处于的地址相同,都位于文字常量区。

#include <func.h>#include <iostream>
using std::cout;
using std::endl;int main(int argc, char *argv[]) {const char *str = "Hello world";printf("str address = %p\n", str);printf("hw  address = %p\n",&"Hello world");return 0;// str address = 0x561f4d567004// hw  address = 0x561f4d567004
}

局部的常量字符串放在栈或者文字常量区,视编译器而定。

7. 程序代码区(只读)

顾名思义,存放程序代码的位置,函数也是存放在某个内存地址的,比如,可以打印看一下main函数的运行地址。

#include <iostream>
using std::cout;
using std::endl;int main(int argc, char *argv[]) {printf("main address =  %p\n", &main);return 0;
}

参考:https://www.cnblogs.com/songdanzju/p/7422507.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/695813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

63-JQuery语法,选择器,事件,方法,遍历循环each,attr(),.prop(),JQuery操作DOM

1.一个JS库,用js封装很多的方法放到一个文件里面,直接拿了用就可以 文件名带min是压缩过的不带min是没压缩过的 2.JQuery语法 通过选取HTML元素,并对选取的元素执行某些操作 基础语法:$(selector).action() <!-- 需要把JQuery文件先引入才能用 --><script src…

IDEA 2021.3激活

1、打开idea&#xff0c;在设置中查找Settings/Preferences… -> Plugins 内手动添加第三方插件仓库地址&#xff1a;https://plugins.zhile.io搜索&#xff1a;IDE Eval Reset 插件进行安装。应用和使用&#xff0c;如图

探秘SuperCLUE-Safety:为中文大模型打造的多轮对抗安全新框架

探秘SuperCLUE-Safety&#xff1a;为中文大模型打造的多轮对抗安全新框架 进入2023年以来&#xff0c;ChatGPT的成功带动了国内大模型的快速发展&#xff0c;从通用大模型、垂直领域大模型到Agent智能体等多领域的发展。但是生成式大模型生成内容具有一定的不可控性&#xff0c…

【数据库】达梦数据库DM8开发版安装

目录 一、达梦数据库概述 1.1 达梦数据库简介 1.2 产品特性 1.3 产品架构 二、安装前准备 2.1 新建 dmdba 用户 2.2 修改文件打开最大数 2.3 挂载镜像 2.4 新建安装目录 2.5 修改安装目录权限 三、数据库安装 3.1 命令行安装 3.2 配置环境变量 四、配置实例 4.1…

LeetCode 热题 100 | 二叉树(下)

目录 1 114. 二叉树展开为链表 2 105. 从前序与中序遍历序列构造二叉树 3 437. 路径总和 III 菜鸟做题&#xff08;即将返校版&#xff09;&#xff0c;语言是 C 1 114. 二叉树展开为链表 题眼&#xff1a;展开后的单链表应该与二叉树 先序遍历 顺序相同。 而先序遍历就…

大语言模型的深度裁剪法

在人工智能领域&#xff0c;大语言模型&#xff08;LLMs&#xff09;已经成为推动语言理解和生成任务进步的重要力量。随着模型规模的不断扩大&#xff0c;如何优化这些模型的计算效率成为了一个迫切需要解决的问题。大型语言模型通常包含数十亿甚至数千亿的参数&#xff0c;这…

四、分类算法 - 朴素贝叶斯算法

目录 1、朴素贝叶斯算法 1.1 案例 1.2 联合概率、条件概率、相互独立 1.3 贝叶斯公式 1.4 朴素贝叶斯算法原理 1.5 应用场景 2、朴素贝叶斯算法对文本进行分类 2.1 案例 2.2 拉普拉斯平滑系数 3、API 4、案例&#xff1a;20类新闻分类 4.1 步骤分析 4.2 代码分析 …

conda下tensorflow安装

conda create -n tf21 python3.7 conda activate tf21 conda install tensorflow-gpu2.1验证 import tensorflow as tf tf.test.is_built_with_cuda()

职业技能鉴定服务中心前端静态页面(官网+证书查询)

有个朋友想做职业技能培训&#xff0c;会发证书&#xff0c;证书可以在自己网站可查。想做一个这样的网站&#xff0c;而且要特别土&#xff0c;一眼看上去像xxx官方网站&#xff0c;像jsp .net技术开发的网站。用htmlcssjquery还原了这样子一个前端页面&#xff0c;这里分享给…

如何使用 GitHub Action 在 Android 中构建 CI-CD

如何使用 GitHub Action 在 Android 中构建 CI-CD 一、什么是 CI/CD&#xff1f;二、什么是 CI&#xff1a;持续集成&#xff1f;三、什么是CD&#xff1a;持续部署&#xff1f;3.1 持续交付3.2 持续部署 四、使用 GitHub 操作在 Android 中构建 CI-CD 管道4.1 步骤 五、什么是…

JAVA工程师面试专题-并发编程篇

目录 一、线程 1、并发与并行的区别 2、同步和异步的区别 3、Java中创建线程有哪些方式? 4、Thread和Runnable的区别 5、Java中的Runnable、Callable、Future、FutureTask的区别和联系&#xff1f; 6、说一下你对 CompletableFuture 的理解 7、volatile关键字有什么用&…

electron学习和新建窗口

首先我们要先下载electron npm install --save-dev electron 建立入口文件main.js 新建一个入口文件 main.js&#xff0c;然后导入eletron新建一个窗口。 const { app, BrowserWindow, ipcMain } require("electron"); const path require("path");func…

centos或者 ubuntu 查找当前目录所有文件包含指定值的文件地址

出现环境是我的nginx缓存 缓存了一个css 但是这个css不是最新的了 所以直接在缓存的目录下执行 find /data -type f -exec grep -l "被缓存文件的内容" {} 找到以后直接vi 查看一下 如果内容没问题的话 直接 rm -rf 删除了就可以了

Async注解详解-Async的作用以及原理

文章目录 起因Async作用原理EnableAsyncAsyncAnnotationBeanPostProcessor 起因 作为一个菜鸟&#xff0c;总是会遇到各种匪夷所思的bug。今天&#xff0c;不出意外的话今天我又遇到了意外…bug… 我在调用同事的一个方法时&#xff0c;莫名奇妙的报了空指针&#xff0c;当前…

压缩感知的图像仿真(MATLAB源代码)

压缩感知是一种用于高效获取和表示信号的技术&#xff0c;它可以显著减少数据的采样和传输量&#xff0c;同时保持对信号的高质量恢复能力。在压缩感知中&#xff0c;信号被表示为其在一个稀疏基中的稀疏线性组合。通过仅使用少量的随机投影测量&#xff0c;就能够捕捉信号的大…

报表控件Stimulsoft 新版本2024.1中,功能区工具栏新功能

今天&#xff0c;我们将讨论Stimulsoft Reports、Dashboards 和 Forms 2024.1版本中的一项重要创新 - 在一行中使用功能区工具栏的能力。 Stimulsoft Ultimate &#xff08;原Stimulsoft Reports.Ultimate&#xff09;是用于创建报表和仪表板的通用工具集。该产品包括用于WinF…

Elasticsearch Update By Query详解

1. 使用场景 一般在以下几种情况时&#xff0c;我们需要重建索引&#xff1a; 索引的 Mappings 发生变更&#xff1a;字段类型更改&#xff0c;分词器及字典更新 索引的 Setting 发生变更&#xff1a;索引的主分片数发生改变 集群内&#xff0c;集群间需要做数据迁移 Elastiic…

【移动安全】MobSF联动安卓模拟器配置动态分析教程

原文链接 MobSF联动安卓模拟器配置动态分析教程 实现方式 Windows开启安卓模拟器并进行相关配置作为调试客户端&#xff0c;Linux使用docker开启MobSF作为服务端。 好处&#xff1a;干净&#xff0c;部署简单&#xff0c;不用安装乱七八糟的环境&#xff0c;防止破坏其他应…

STM32F10X(Cortex-M3)系统定时器寄存器笔记和系统定时器精准延时函数

Cortex-M3系统定时器寄存器笔记和系统定时器精准延时函数 简介系统定时器寄存器STK_CTRLSTK_LOADSTK_VALSTK_CALIB STM32F10X(Cortex-M3)精准延时函数 简介 在STM32F10X(Cortex-M3)除了通用定时器和看门狗定时器外&#xff0c;还有一个系统定时器(SysTick) 拿STM32F103C8T6来说…

ES6 | (一)ES6 新特性(上) | 尚硅谷Web前端ES6教程

文章目录 &#x1f4da;ES6新特性&#x1f4da;let关键字&#x1f4da;const关键字&#x1f4da;变量的解构赋值&#x1f4da;模板字符串&#x1f4da;简化对象写法&#x1f4da;箭头函数&#x1f4da;函数参数默认值设定&#x1f4da;rest参数&#x1f4da;spread扩展运算符&a…