用Visual Studio 2022的.map文件来查看C++变量在内存中的布局情况

这篇具有很好参考价值的文章主要介绍了用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段(Block Started by Symbol Segment)中,只存符号(只有占位符),没有初始化的具体的值,自然也就不需要在二进制文件中保存这些值,因此文件很小。

        而后两份代码中data_arr变量定义并初始化为具体的值,此变量运行时实际会存放到data段中,又因为初始化了具体的值,这些值需要保存在二进制程序源文件中,所以文件就变大了。

确认data_arr变量在内存中的布局

        在Visual Studio 2022中用对应的.map文件,来确认data_arr变量在内存中的具体布局情况,看看它们运行时到底存放在哪个内存段中。

        生成.map和了解.map文件内容请见: Visual Studio(2022)生成链接过程的.map映射文件以及.map映射文件的内容说明_含影的博客-CSDN博客

        前两份代码对应的的.map文件摘录如下:

Preferred load address is 0000000140000000
 Start         Length     Name                   Class
 0001:000013d0 00000091H .text$x                 CODE
 0002:00000ec8 00000788H .idata$6                DATA
 0003:00000000 00000040H .data                   DATA
 0003:00000040 00020088H .bss                    DATA
 0004:00000000 00000240H .pdata                  DATA

  Address         Publics by Value              Rva+Base               Lib:Object

 0003:00000030       __scrt_ucrt_dll_is_in_use  0000000140005030     MSVCRT:ucrt_stubs.obj
 0003:00000040       ?data_arr@@3PAHA           0000000140005040     ccwindowsMain.obj

        从上面的.map文件内容,可以看到,data_arr变量,被分配到地址为0003:00000040这个内存空间中,而这个内存空间就是bss段(见于:0003:00000040 00020088H .bss)。

        后两份代码对应的的.map文件摘录如下:

 demo_ccwindows
 Preferred load address is 0000000140000000

 Start         Length     Name                   Class
 0001:00000000 00001390H .text$mn                CODE
 0002:00000ec8 00000788H .idata$6                DATA
 0003:00000000 00020040H .data                   DATA
 0003:00020040 00000088H .bss                    DATA
 0004:00000000 00000240H .pdata                  DATA

  Address         Publics by Value              Rva+Base               Lib:Object

 0002:00000c90       __NULL_IMPORT_DESCRIPTOR   0000000140003c90     msvcprt:MSVCP140.dll
 0003: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 0000000140000000

 Start         Length     Name                   Class
 0001:00000000 00000050H .text$di                CODE
 0001:00000050 000021a0H .text$mn                CODE
 0001:000021f0 00000040H .text$mn$00             CODE
 0001:00002230 000000c0H .text$x                 CODE
 0001:000022f0 00000064H .text$yd                CODE
 0002:00000000 00000278H .idata$5                DATA
 0002:00000278 00000038H .00cfg                  DATA
 0002:000002b0 00000008H .CRT$XCA                DATA
 0002:000002b8 00000008H .CRT$XCAA               DATA
 0002:000002c0 00000008H .CRT$XCU                DATA
 0002:000002c8 00000008H .CRT$XCZ                DATA
 0002:000002d0 00000008H .CRT$XIA                DATA
 0002:000002d8 00000008H .CRT$XIAA               DATA
 0002:000002e0 00000008H .CRT$XIAC               DATA
 0002:000002e8 00000008H .CRT$XIZ                DATA
 0002:000002f0 00000008H .CRT$XPA                DATA
 0002:000002f8 00000008H .CRT$XPZ                DATA
 0002:00000300 00000008H .CRT$XTA                DATA
 0002:00000308 00000008H .CRT$XTZ                DATA
 0002:00000310 00000000H .gehcont$y              DATA
 0002:00000310 00000000H .gfids$y                DATA
 0002:00000310 000002f0H .rdata                  DATA
 0002:00000600 00000080H .rdata$CastGuardVftablesA DATA
 0002:00000680 00000080H .rdata$CastGuardVftablesC DATA
 0002:00000700 000001f4H .rdata$r                DATA
 0002:000008f4 000000a8H .rdata$voltmd           DATA
 0002:0000099c 000003c4H .rdata$zzzdbg           DATA
 0002:00000d60 00000008H .rtc$IAA                DATA
 0002:00000d68 00000008H .rtc$IZZ                DATA
 0002:00000d70 00000008H .rtc$TAA                DATA
 0002:00000d78 00000008H .rtc$TZZ                DATA
 0002:00000d80 00000418H .xdata                  DATA
 0002:00001198 000000ecH .xdata$x                DATA
 0002:00001284 00000000H .edata                  DATA
 0002:00001284 000000b4H .idata$2                DATA
 0002:00001338 00000018H .idata$3                DATA
 0002:00001350 00000278H .idata$4                DATA
 0002:000015c8 00000868H .idata$6                DATA
 0003:00000000 00020078H .data                   DATA
 0003:00020078 00000080H .data$r                 DATA
 0003:000200f8 00000028H .data$rs                DATA
 0003:00020120 000005f0H .bss                    DATA
 0004:00000000 000003b4H .pdata                  DATA
 0005:00000000 00000060H .rsrc$01                DATA
 0005:00000060 00000180H .rsrc$02                DATA

  Address         Publics by Value              Rva+Base               Lib:Object
  
 0003:00000000       ?data_arr@@3PAHA           0000000140006000     ccwindowsMain.obj
 0002:000003a8       ?Major_version@@3HD        00000001400043a8     ccwindowsMain.obj
 0002:000003ac       ?Minor_Version@@3MD        00000001400043ac     ccwindowsMain.obj
 0003:00020020       ?baseSignal@?1??parseSignal@@YAHH@Z@4HA 0000000140026020     ccwindowsMain.obj
 0003:00020000       ?base_str_0@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A 0000000140026000     ccwindowsMain.obj
 0002:000002c0       ?base_str_0$initializer$@@3P6AXXZEA 00000001400042c0     ccwindowsMain.obj
 0002:00000310       ??_C@_0BA@DGGOEDOG@sssssAAAAA00000@ 0000000140004310     ccwindowsMain.obj
 0002:000003b0       ??_C@_0BA@GADHIFOA@sssssAAAAA11111@ 00000001400043b0     ccwindowsMain.obj
 0002:000003c0       ??_C@_0BA@JKNNMPOK@sssssAAAAA22222@ 00000001400043c0     ccwindowsMain.obj

由以上代码可以看到, Major_version和Minor_Version放在只读数据区(.rdata),baseSignal这个局部静态变量放在.data数据段,而字符串常量放在只读数据段.rdata。

注:这里用 volatile 是为了防止编译器优化。

可以在 Visual Studio 项目的 连接器 -> 系统 -> 堆栈保留大小 这里按照字节数设置当前程序的默认堆栈大小。文章来源地址https://www.toymoban.com/news/detail-694857.html

到了这里,关于用Visual Studio 2022的.map文件来查看C++变量在内存中的布局情况的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】1-1.7 下载安装Visual Studio 2022

    windows操作系统上,C++程序开发的最佳IDE还是Visual Studio。 Visual Studio是一般指的是Microsoft Visual Studio(简称VS)。 VS是美国微软公司的开发工具包系列产品。 Visual Studio是最流行的Windows平台应用程序的集成开发环境。 最新版本为 Visual Studio 2022 [17] 版本,基于.NET Framework 4.8 。

    2024年02月05日
    浏览(66)
  • Visual Studio2022 生成可执行文件

    解决方案改为 Release : 找到项目 → rightarrow → 项目名称属性,如示例项目的名称为 Project1 ,就找到下图所示的选项并进入: 在配置属性 → rightarrow → C/C++ → rightarrow → 代码生成中,找到运行库,并设为 多线程(/MT) : 如果想要修改生成的 .exe 文件的名字,在配置属性

    2024年02月12日
    浏览(44)
  • Visual Studio 2022 CMake C++ Hello World

    C++自学精简教程 目录(必读) Visual Studio 2022 安装​​​​​​​ 什么是CMake CMake是跨平台的C/C++工程构建工具。 我们知道, 在Windows上用Visual Studio开发C/C++代码,工程文件是用.vcxproj文件来组织的; 在Linux上用gcc/g++开发C/C++代码,工程文件是用Makefile文件来组织的; 很多时候我

    2024年02月16日
    浏览(52)
  • 使用 Visual Studio 2022 开发 Linux C++ 应用程序

    前置条件: Windows上需要先安装 WSL2,方法见: Install WSL | Microsoft Docs 在 WSL2 中依次执行如下命令,进行安装如下必需软件: Visual Studio 2022 引入了用于 Linux C++ 开发的本机 WSL2 工具集,可以构建和调试 Linux C++ 代码,并提供了非常好的 Linux 文件系统性能、GUI 支持和完整的系统

    2024年02月05日
    浏览(118)
  • STM32查看内存占用的map文件解析

    双击工程名尽可打开xxx.map文件,里面主要显示了文件及函数使用内存的大小 堆:是用户调用malloc()时申请的内存; 栈:是提供给局部变量使用的,即由c语言机制自动申请和释放; 1.2 flash、ROM、RAM的区别 在stm32中flash就是ROM,掉电数据不会丢失;(通常保存着text段、Code、R

    2024年02月11日
    浏览(41)
  • C++ 学习(一)Visual Studio 2022配置、Git配置及第一个程序

    从今天开始学习一下C++,一些小例子与Golang语言对比一下。 C++ IDE:Visual Studio 2022 下载地址:Visual Studio 2022 IDE - Programming Tool for Software Developers Golang IDE:Goland (需要配置Go环境) 下载地址:Download GoLand: A Go IDE with extended support for JavaScript, TypeScript, and databases 选择“创建新项

    2023年04月09日
    浏览(56)
  • C++计算机视觉库OpenCV在Visual Studio 2022的配置方法

      本文介绍在 Visual Studio 2022 中配置、编译 C++ 计算机视觉库 OpenCV 的方法。   首先,我们进行 OpenCV 库的下载与安装。作为一个开源的库,我们直接在其官方下载网站(https://opencv.org/releases/)中进行下载即可;如下图所示,我们首先选择需要下载的操作系统。   随后

    2024年02月16日
    浏览(60)
  • visual studio 2022 头文件和库目录问题造成的编译失败

    新安装visual studio 2022后,在一个简单工程上编译测试中,遇到标准头文件(new.h)报错,详情如下: 经验证和对比visual studio 2019,发现visual studio 2022以下sdk路径有一个明显差异。详情如下所示。 visual studio 2019 安装后的默认路径如下 而 visual studio 2022路径如下 库目录也一样不

    2023年04月08日
    浏览(99)
  • Window中,Visual Studio 2022(C++)环境下安装OpenCV教程(不用Cmake版本)

    本教程主要为了方便小白安装C++版本的OpenCV。 1. 第一步:下载官方OpenCV 下载后,在本地安装即可,注意记住安装路径,后续需要! 2. 配置系统环境变量,Path中,新增变量。即opencv安装的路径,选到opencv中build/x64/vc15/bin 3. 安装visual studio 2022,官网 直接,按照C++配置安装即可

    2024年02月11日
    浏览(63)
  • 在visual studio 2022 C++中配置最新版OpenCV和可能错误解决方案

    前面我们写了一篇博文有关在C#中配置OpenCV,但C#版本的OpenCV的学习资源相对较少,C++版的和Python版的比较多。这里先说说C++版的如何配置吧!总共完成四步即可使用起来。 文章原出处: https://blog.csdn.net/haigear/article/details/129617330 我们来到官网,最新版截止到22年12月的4.7,无

    2024年02月05日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包