用Visual Studio 2022的.map文件来查看C++变量在内存中的布局情况
先看几个实例
代码1
#include <iostream>
int data_arr[32768];
int main()
{data_arr[1] += 11;std::cout<<"data_arr[1]: " << data_arr[1] << std::endl;return data_arr[1];
}
上述代码在Win10 X64,MSVC Release模式下编译,编译得到的二进制文件大小为15KB左右。
代码2
#include <iostream>
int data_arr[32768] = {0,0,0,0,0};
int main()
{data_arr[1] += 11;std::cout<<"data_arr[1]: " << data_arr[1] << std::endl;return data_arr[1];
}
上述代码在Win10 X64,MSVC Release模式下编译,编译得到的二进制文件大小为15KB左右。
代码3
#include <iostream>
int data_arr[32768] = {2};
int main()
{data_arr[1] += 11;std::cout<<"data_arr[1]: " << data_arr[1] << std::endl;return data_arr[1];
}
上述代码在Win10 X64,MSVC Release模式下编译,编译得到的二进制文件大小为143KB左右。
代码4
#include <iostream>
int data_arr[32768] = {1,2,3,4,5,6};
int main()
{data_arr[1] += 11;std::cout<<"data_arr[1]: " << data_arr[1] << std::endl;return data_arr[1];
}
上述代码在Win10 X64,MSVC Release模式下编译,编译得到的二进制文件大小为143KB左右。
情况分析
为何前两份代码和后两份代码编译之后的二进制文件大小会差异这么大?
原因就是全局变量data_arr 定义的方式不同。前两份代码中data_arr变量定义但是没有初始化或初始化为0,此变量运行时实际会存放在bss段中,只存符号(只有占位符),没有初始化的具体的值,自然也就不需要在二进制文件中保存这些值,因此文件很小。
而后两份代码中data_arr变量定义并初始化为具体的值,此变量运行时实际会存放到data段中,又因为初始化了具体的值,这些值需要保存在二进制程序源文件中,所以文件就变大了。
确认data_arr变量在内存中的布局
在Visual Studio 2022中用对应的.map文件,来确认data_arr变量在内存中的具体布局情况,看看它们运行时到底存放在哪个内存段中。
生成.map和了解.map文件内容请见: Visual Studio(2022)生成链接过程的.map映射文件以及.map映射文件的内容说明_含影的博客-CSDN博客
前两份代码对应的的.map文件摘录如下:
Preferred load address is 0000000140000000Start Length Name Class0001:000013d0 00000091H .text$x CODE0002:00000ec8 00000788H .idata$6 DATA0003:00000000 00000040H .data DATA0003:00000040 00020088H .bss DATA0004:00000000 00000240H .pdata DATAAddress Publics by Value Rva+Base Lib:Object0003:00000030 __scrt_ucrt_dll_is_in_use 0000000140005030 MSVCRT:ucrt_stubs.obj0003:00000040 ?data_arr@@3PAHA 0000000140005040 ccwindowsMain.obj
从上面的.map文件内容,可以看到,data_arr变量,被分配到地址为0003:00000040这个内存空间中,而这个内存空间就是bss段(见于:0003:00000040 00020088H .bss)。
后两份代码对应的的.map文件摘录如下:
demo_ccwindowsPreferred load address is 0000000140000000Start Length Name Class0001:00000000 00001390H .text$mn CODE0002:00000ec8 00000788H .idata$6 DATA0003:00000000 00020040H .data DATA0003:00020040 00000088H .bss DATA0004:00000000 00000240H .pdata DATAAddress Publics by Value Rva+Base Lib:Object0002:00000c90 __NULL_IMPORT_DESCRIPTOR 0000000140003c90 msvcprt:MSVCP140.dll0003:00000000 ?data_arr@@3PAHA 0000000140005000 ccwindowsMain.obj
从上面的.map文件内容,可以看到,data_arr变量,被分配到地址为0003:00000000这个内存空间中,而这个内存空间就是data段(见于:0003:00000000 00020040H .data)。
复杂一点的代码示例
#include <iostream>
#include <string>
int data_arr[32768] = {1, 2, 3, 4, 5, 6, 7, 8};
volatile const static int Major_version = 22;
volatile const float Minor_Version = 17;
std::string base_str_0 = "sssssAAAAA00000";
int parseSignal(int signal)
{static int baseSignal = 1013;std::string base_str = "sssssAAAAA11111";if (signal > 15){base_str += "sssssAAAAA22222" + base_str_0;signal *= base_str.size();}return signal * baseSignal;
}
int main(int argc, char** argv)
{data_arr[1] += 11;std::cout << "data_arr[1]: " << data_arr[1] << std::endl;return data_arr[1] + (Major_version << argc) + Minor_Version * argc + parseSignal(argc >> 1);
}
对应的.map内容节选如下:
Preferred load address is 0000000140000000Start Length Name Class0001:00000000 00000050H .text$di CODE0001:00000050 000021a0H .text$mn CODE0001:000021f0 00000040H .text$mn$00 CODE0001:00002230 000000c0H .text$x CODE0001:000022f0 00000064H .text$yd CODE0002:00000000 00000278H .idata$5 DATA0002:00000278 00000038H .00cfg DATA0002:000002b0 00000008H .CRT$XCA DATA0002:000002b8 00000008H .CRT$XCAA DATA0002:000002c0 00000008H .CRT$XCU DATA0002:000002c8 00000008H .CRT$XCZ DATA0002:000002d0 00000008H .CRT$XIA DATA0002:000002d8 00000008H .CRT$XIAA DATA0002:000002e0 00000008H .CRT$XIAC DATA0002:000002e8 00000008H .CRT$XIZ DATA0002:000002f0 00000008H .CRT$XPA DATA0002:000002f8 00000008H .CRT$XPZ DATA0002:00000300 00000008H .CRT$XTA DATA0002:00000308 00000008H .CRT$XTZ DATA0002:00000310 00000000H .gehcont$y DATA0002:00000310 00000000H .gfids$y DATA0002:00000310 000002f0H .rdata DATA0002:00000600 00000080H .rdata$CastGuardVftablesA DATA0002:00000680 00000080H .rdata$CastGuardVftablesC DATA0002:00000700 000001f4H .rdata$r DATA0002:000008f4 000000a8H .rdata$voltmd DATA0002:0000099c 000003c4H .rdata$zzzdbg DATA0002:00000d60 00000008H .rtc$IAA DATA0002:00000d68 00000008H .rtc$IZZ DATA0002:00000d70 00000008H .rtc$TAA DATA0002:00000d78 00000008H .rtc$TZZ DATA0002:00000d80 00000418H .xdata DATA0002:00001198 000000ecH .xdata$x DATA0002:00001284 00000000H .edata DATA0002:00001284 000000b4H .idata$2 DATA0002:00001338 00000018H .idata$3 DATA0002:00001350 00000278H .idata$4 DATA0002:000015c8 00000868H .idata$6 DATA0003:00000000 00020078H .data DATA0003:00020078 00000080H .data$r DATA0003:000200f8 00000028H .data$rs DATA0003:00020120 000005f0H .bss DATA0004:00000000 000003b4H .pdata DATA0005:00000000 00000060H .rsrc$01 DATA0005:00000060 00000180H .rsrc$02 DATAAddress Publics by Value Rva+Base Lib:Object0003:00000000 ?data_arr@@3PAHA 0000000140006000 ccwindowsMain.obj0002:000003a8 ?Major_version@@3HD 00000001400043a8 ccwindowsMain.obj0002:000003ac ?Minor_Version@@3MD 00000001400043ac ccwindowsMain.obj0003:00020020 ?baseSignal@?1??parseSignal@@YAHH@Z@4HA 0000000140026020 ccwindowsMain.obj0003:00020000 ?base_str_0@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A 0000000140026000 ccwindowsMain.obj0002:000002c0 ?base_str_0$initializer$@@3P6AXXZEA 00000001400042c0 ccwindowsMain.obj0002:00000310 ??_C@_0BA@DGGOEDOG@sssssAAAAA00000@ 0000000140004310 ccwindowsMain.obj0002:000003b0 ??_C@_0BA@GADHIFOA@sssssAAAAA11111@ 00000001400043b0 ccwindowsMain.obj0002:000003c0 ??_C@_0BA@JKNNMPOK@sssssAAAAA22222@ 00000001400043c0 ccwindowsMain.obj
由以上代码可以看到, Major_version和Minor_Version放在只读数据区(.rdata),baseSignal这个局部静态变量放在.data数据段,而字符串常量放在只读数据段.rdata。
注:这里用 volatile 是为了防止编译器优化。
相关文章:
用Visual Studio 2022的.map文件来查看C++变量在内存中的布局情况
先看几个实例 代码1 #include <iostream> int data_arr[32768]; int main() {data_arr[1] 11;std::cout<<"data_arr[1]: " << data_arr[1] << std::endl;return data_arr[1]; } 上述代码在Win10 X64,MSVC Release模式下编译&…...
使用代理突破浏览器IP限制
一、实验目的: 主要时了解代理服务器的概念,同时如何突破浏览器IP限制 二、预备知识: 代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站,特别是它具有一个cac…...
HuggingFace中的 Files and versions 如何优雅下载到本地?(Python requests,tqdm)
前言 在使用huggingface把玩各种大模型时,如果选择从远程加载模型,这个过程可能因为网络问题而非常耗时甚至直接失败,所以把模型、分词器等相关文件下载到本地,再直接从本地加载就成了不可回避的流程。 在进入具体版本的模型后&…...
三、原型模式
一、什么是原型模式 原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效&a…...
transformer实现词性标注
1、self-attention 1.1、self-attention结构图 上图是 Self-Attention 的结构,在计算的时候需要用到矩阵 Q(查询), K(键值), V(值)。在实际中,Self-Attention 接收的是输入(单词的表示向量 x组成的矩阵 X) 或者上一个 Encoder block 的输出。而 Q, K, V…...
Java中异或操作和OTP算法
最近在研究加密算法,发现异或操作在加密算法中用途特别广,也特别好用。下面以Java语言为例,简单记录一下异或操作,以及在算法中的使用,包括常用的OTP算法。 一,异或操作特征 1, 相同出0&#…...
K8S最新版本集群部署(v1.28) + 容器引擎Docker部署(下)
温故知新 📚第三章 Kubernetes各组件部署📗安装kubectl(可直接跳转到安装kubeadm章节,直接全部安装了)📕下载kubectl安装包📕执行kubectl安装📕验证kubectl 📗安装kubead…...
女子垒球运动的发展·垒球1号位
女子垒球运动的发展 1. 女子垒球运动的起源和发展概述 女子垒球运动,诞生于19世纪末的美国,作为棒球运动的衍生品,经过百年的积淀,已在全球范围内广泛传播,形成了丰富的赛事文化。她的起源,可以追溯到19世…...
Debian 30 周年,生日快乐!
导读近日是 Debian 日,也是由伊恩-默多克(Ian Murdock)创立的 Debian GNU/Linux 通用操作系统和社区支持的 Debian 项目 30 周年纪念日。 不管你信不信,从已故的伊恩-默多克于 1993 年 8 月 16 日宣布成立 Debian 项目,…...
字符串匹配的Rabin–Karp算法
leetcode-28 实现strStr() 更熟悉的字符串匹配算法可能是KMP算法, 但在Golang中,使用的是Rabin–Karp算法 一般中文译作 拉宾-卡普算法,由迈克尔拉宾与理查德卡普于1987年提出 “ 要在一段文本中找出单个模式串的一个匹配,此算法具有线性时间的平均复杂度࿰…...
傅里叶变换(FFT)笔记存档
参考博客:https://www.luogu.com.cn/blog/command-block/fft-xue-xi-bi-ji 目录: FFT引入复数相关知识单位根及其相关性质DFT过程(难点)DFT结论(重要)IDFT结论(重要)IDFT结论证明&…...
ELK安装、部署、调试 (二) ES的安装部署
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口操作ES,也可以利用Java API。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业…...
Android 13 - Media框架(8)- MediaExtractor
上一篇我们了解了 GenericSource 需要依赖 IMediaExtractor 完成 demux 工作,这一篇我们就来学习 android media 框架中的第二个服务 media.extractor,看看 IMediaExtractor 是如何创建与工作的。 1、MediaExtractorService media.extractor 和 media.p…...
Flutter 混合开发调试
针对Flutter开发的同学来说,大部分的应用还是Native Flutter的混合开发,所以每次改完Flutter代码,运行整个项目无疑是很费时间的。所以Flutter官方也给我们提供了混合调试的方案【在混合开发模式下进行调试】,这里以Android Stud…...
C语言每日一练------(Day3)
本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今天练习题的关键字: 尼科彻斯定理 等差数列 💓博主csdn个人主页:…...
14、监测数据采集物联网应用开发步骤(10)
监测数据采集物联网应用开发步骤(9.2) Modbus rtu协议开发 本章节在《监测数据采集物联网应用开发步骤(7)》基础上实现可参考《...开发步骤(7)》调试工具,本章节代码需要调用modbus_tk组件,阅读本章节前建议baidu熟悉modbus rtu协议内容 组件安装modb…...
Linux禅道上修改Apache 和 MySQL 默认端口号
1. 修改Apache默认端口号 80 cd /opt/zbox/etc/apachevim httpd.conf :wq 保存 2. 修改MySQL默认端口号 3306 cd /opt/zbox/etc/mysql vim my.cnf :wq 保存 3. 重启服务 ./zbox restart...
操作教程|通过1Panel开源Linux面板快速安装DataEase
DataEase开源数据可视化分析工具(dataease.io)的在线安装是通过在服务器命令行执行Linux命令来进行的。但是在实际的安装部署过程中,很多数据分析师或者业务人员经常会因为不熟悉Linux操作系统及命令行操作方式,在安装DataEase的过…...
机器学习策略——优化深度学习系统
正交化(Orthogonalization) 老式电视机,有很多旋钮可以用来调整图像的各种性质,对于这些旧式电视,可能有一个旋钮用来调图像垂直方向的高度,另外有一个旋钮用来调图像宽度,也许还有一个旋钮用来…...
ES6中Proxy和Proxy实例
1.Proxy Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器” 使用方法 let p new Proxy(target, handler);其中,target 为被代理对象。handler 是一个对象,其声明了代理 target 的一些操作。p 是…...
基于NLP-StructBERT的智能客服语义匹配实战:Java微服务集成
基于NLP-StructBERT的智能客服语义匹配实战:Java微服务集成 你有没有遇到过这种情况?用户问“我的订单怎么还没发货”,而你的知识库里只有“订单发货状态查询”这样的标准问题。传统的关键词匹配,比如搜索“订单”和“发货”&…...
ROS 2 手眼标定完整方案
我给你整理ROS 2 中最稳定、最常用、工业级可用的手眼眼标定包,包含安装、使用、命令、区别,直接照着用就行。 一、ROS 2 首选手眼标定包:easy_handeye2 github 地址:https://github.com/IFL-CAMP/easy_handeye2 这是 easy_hand…...
SMT波浪焊接工艺精准控制品质核心
SMT波浪焊接过程中,设备是基础,而工艺参数的精准控制则是决定焊接质量的核心。很多电子制造企业都会遇到这样的问题:同样的设备、同样的原材料,不同批次的产品焊接质量却参差不齐,有的焊点牢固、外观规整,有…...
如何快速恢复华硕笔记本色彩配置文件:G-Helper智能修复方案
如何快速恢复华硕笔记本色彩配置文件:G-Helper智能修复方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Stri…...
OpenClaw FPGA资源利用率优化深度指南
OpenClaw FPGA资源利用率优化深度指南🔧 核心价值:OpenClaw实现"资源分析→智能优化→验证→部署"全流程自动化,资源利用率平均提升45%,功耗降低38%,时序性能提升28%,支持Xilinx/Intel FPGA全系列…...
如何用Python解析LRMX文件:干部管理系统开发实战(附完整代码)
Python解析LRMX文件实战:构建高效干部管理系统 在组织人事管理领域,LRMX文件作为标准数据交换格式,承载着干部任免审批的核心信息。本文将深入探讨如何利用Python技术栈实现LRMX文件的自动化处理,构建一个功能完整的干部管理系统。…...
Apache Parquet Java性能优化秘籍:5个关键技巧提升读写速度300%
Apache Parquet Java性能优化秘籍:5个关键技巧提升读写速度300% 【免费下载链接】parquet-java Apache Parquet Java 项目地址: https://gitcode.com/gh_mirrors/pa/parquet-java Apache Parquet Java是处理大数据列式存储的终极解决方案,通过合理…...
实战指南:基于快马平台快速开发并部署班级宠物园应用官方下载门户
最近学校想推广一个班级宠物园的教育应用,需要快速搭建一个官方下载页面。作为技术负责人,我尝试用InsCode(快马)平台来快速实现这个需求,整个过程比想象中顺利很多。 项目规划与结构设计 首先明确页面需要包含的几个核心模块:顶部…...
想了解欧拉好猫参数?这篇文章给你详细答案!
在当今新能源汽车市场蓬勃发展的背景下,欧拉好猫凭借其独特的魅力,在众多车型中脱颖而出,吸引了众多消费者的目光。以下将对欧拉好猫的相关参数及技术亮点进行详细解析。外观设计与尺寸欧拉好猫采用复古未来主义的设计风格,圆润的…...
iMeta | 浙江农科院卢立志/曾涛联合中南大学湘雅医院揭示人参皂苷Rg3缓解肝脏铁死亡的新机制
点击蓝字 关注我们一种生物活性人参皂苷改善非酒精性脂肪性肝炎中氧化磷脂积累引起的肝细胞铁死亡iMeta主页:http://www.imeta.science研究论文● 原文: iMeta(IF 33.2, 中科院双一区Top)● 英文题目: A bioactive ginsenoside alleviates hepatocellular ferroptos…...
