C++程序的内存布局
对任何一个普通C++程序来讲,它都会涉及到5种不同的数据段。常用的几个数据段种包含有“程序代码段”、“程序数据段”、“程序堆栈段”等。不错,这几种数据段都在其中,但除了以上几种数据段之外,进程还另外包含两种数据段。下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区。
代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存种的镜像。代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作——它是不可写的。
数据段:数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量。
BSS段:BSS段包含了程序中未初始化全局变量,在内存中bss段全部置零。
堆(heap):堆是用于存放进程运行中被动态分配的内存段,它大小并不固定,可动态扩张或缩减。当进程调用malloc/new等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
栈:栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味这在数据段中存放变量)。除此以外在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也回被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上将我们可以把堆栈看成一个临时数据寄存、交换的内存区。
我们要知道,栈中存放的是一个个被调函数所对应的堆栈帧,当函数fun1被调用,则fun1的堆栈帧入栈,fun1返回时,fun1的堆栈帧出栈。什么是堆栈帧呢,堆栈帧其实就是保存被调函数返回时下一条执行指令的指针、主调函数的堆栈帧的指针、主调函数传递给被调函数的实参(如果有的话)、被调函数的局部变量等信息的一个结构。
首先,我们要说明的是如何区分每个堆栈帧,或者说,如何知道我现在在使用哪个堆栈帧。和栈密切相关的有2个寄存器,一个是ebp,一个是esp,前者可以叫作栈基址指针,后者可以叫栈顶指针。对于一个堆栈帧来说,ebp也叫堆栈帧指针,它永远指向这个堆栈帧的某个固定位置(见上图),所以可以根据ebp来表示一个堆栈帧,可以通过对ebp的偏移加减,来在堆栈帧中来来回回的访问。esp则是随着push和pop而不断移动。因此根据esp来对堆栈帧进行操作。
再来讲一下上图,一个堆栈帧的最顶部,是实参,然后是return address,这个值是由主调函数中的call命令在call调用时自动压入的,不需要我们关心,previousframe pointer,就是主调函数的堆栈帧指针,也就是主调函数的ebp值。ebp偏移为正的都是被调函数的局部变量。
C++程序的内存布局相关推荐
- 栈、堆、静态存储区和程序的内存布局
文章目录 1 栈 1.1 程序中的栈 1.2 函数调用过程 1.3 函数调用栈上的数据 2 堆 2.1 程序中的堆 2.2 系统对堆的管理方式 3 静态存储区 3.1 程序中的静态存储区 4 程序的内 ...
- linux程序内存布局,关于Linux中程序的内存布局
我有一些关于Linux中的程序的内存布局的问题. 我知道从各种来源(我正在读"从头开始编程"),每个部分都加载到它自己的内存区域. 文本部分首先在虚拟地址0x8048000处加载, ...
- Linux下C语言程序的内存布局(内存模型)
在<虚拟地址空间以及编译模式>一节中讲到,虚拟地址空间在32位环境下的大小为 4GB,在64位环境下的大小为 256TB,那么,一个C语言程序的内存在整个地址空间中是如何分布的呢?数据在哪 ...
- 【C语言进阶深度学习记录】三十六 程序与进程的区别(程序的内存布局)
上一篇文章学了堆,栈以及静态存储区.它们实际上都是针对进程来说的.那么程序与进程有什么区别呢? 本文不细讲程序与进程. 1 程序与进程 1.1 什么是程序 写完的.c文件是源文件.也叫源代码. 将源代 ...
- windows c语言能分配多少内存,Windows下C语言程序的内存布局(内存模型)
转载,详见原文:https://www.cnblogs.com/zhangjinfu/articles/11275966.html 在32位环境下,Windows 默认会将高地址的 2GB 空间分配给 ...
- Linux下C语言程序的内存布局
以下内容源于C语言中文网的内容学习与整理.如有侵权,请告知删除.
- 程序在内存中运行的奥秘
简介 当丰富多彩的应用程序在计算机上运行,为你每天的工作和生活带来便利时,你是否知道它们是如何在计算机中工作呢?本文用形象的图表与生动的解释,揭示了程序在计算机中运行的奥秘. 内存管理是操作系统的核心 ...
- 内存管理-定时器循环、内存布局、tagged pointer、weak指针、copy、自动释放池
先上代码,我们平时用的定时器,cadisplaylink.nstimer,CADisplayLink.NSTimer会对target产生强引用,如果target又对它们产生强引用,那么就会引发循环引用 ...
- linux系统进程的内存布局
内存管理模块是操作系统的心脏:它对应用程序和系统管理非常重要.今后的几篇文章中,我将着眼于实际的内存问题,但也不避讳其中的技术内幕.由于不少概念是通用的,所以文中大部分例子取自32位x86平台的Lin ...
最新文章
- Visual Assist X 10.8.2036的Crack破解补丁.2014.05.22 (General release.)
- hdu 2009 求数列的和(c语言)
- mybatis第一讲:初探mybatis实现简单的查询
- Oracle导入导出数据
- 如何存储 Git 大文件?
- leetcode1247. 交换字符使得字符串相同(贪心)
- TensorFlow训练单特征和多特征的线性回归
- CentOS7 安装 NextCloud
- Exchange 2013SP1和O365混合部署系列二
- input 标签左对齐
- php主页备案号底部中间,如何获取公安备案号?如何将公安备案号放到网站底部?...
- Chromium OS Autotest 概述
- 浏览器内核控制Meta标签说明文档(360浏览器默认极速模式)
- 设计模式 装饰者模式 带你重回传奇世界
- Telegram APIs中文介绍
- 无法找到合适的显示设备.正在关闭程序
- swagger 接口参数顺序_swagger扩展为按代码定义顺序展示接口和字段
- 如何评价微擎?怎么看待微擎模块应用?
- PMP——第4章 项目整合管理
- AI大模型加持,生成式搜索来了!
热门文章
- 【Java 虚拟机原理】栈帧 | 动态链接 | 方法区 | 字节码文件二进制分析
- 【Android 安装包优化】WebP 应用 ( Android 中使用 libwebp.so 库解码 WebP 图片 )
- 【Android RTMP】NV21 图像旋转处理 ( 问题描述 | 图像顺时针旋转 90 度方案 | YUV 图像旋转细节 | 手机屏幕旋转方向 )
- 【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )
- 【IOS 开发】基本 UI 控件详解 (UIDatePicker | UIPickerView | UIStepper | UIWebView | UIToolBar )
- 关于 Capella 需要纠正的语音
- node.js入门系列(一)--Node.js简介
- struts2-20-下载文件及授权控制
- POJ 1741 Tree(树分治)
- c# C++接口封装 汽车模拟仿真