C++内存的分区
内存一共4个区
1.任何在函数内部声明的非static变量,其变量地址本身在栈区。栈是向低地址扩展的数据结构,即栈顶的地址和栈的最大容量是系统预先规定好的。
2.任何全局变量或者静态局部变量,其变量地址本身在全局区
3.任何指针变量 如果用malloc,relloc,calloc,或者c++中的new ,指针指向的内存在堆区。堆是向高地址扩展的
4.代码、字符常量在代码区

其中.bss段和.data段为全局区,.bss段存储还未初始化的全局变量,.data段则存储已初始化的全局变量,.text段是代码区。
char sz[] = {'s','t','r','i','n','g','/0'}; 如果在函数内部出现的话,这几个字符将存放在堆栈中,所以不是字符串常量。
char *psz = "string"; 这条语句,该语句定义了一个指向"string"字符串的指针,并没有空间存放"string"字符串,显然把“string”当做字符串常量并存放在常量区是最合适的选择。并且语句 psz[4] = 'x'; 在编译时不会报错,执行时会产生异常,原因是“string”存放在只读存储区,不可以修改。这和C++中 const char *psz = "string";一句是一样的,所以最好显示的加上const关键字从而让编译器检测出“修改常量“错误。
如:void foo(char sz[100], int ival[10]);
答案是将其理解为指针的形式:
void foo(char *sz, int *ival);
int a = ; //全局区
int main()
{
char *b = "Hello!~~"; //指针指向代码区,b变量本身也在栈区
int c = ; //栈区
int *d = (int*)malloc( sizeof(int) ); //指针指向堆区,d变量本身同样在栈区
*d = ;
static char e = ; //全局区
static int (*f)() = main; //指向代码区,f本身在全局区
return ;
}
例3:函数递归是通过栈来实现的,栈中是函数返回地址
procedure A1(…); procedure A2(…); procedure A3(…);
begin begin begin
┇ ┇ ┇
r:A2(…); t:A3(…); end;
r1:┇ t1: ┇
end; end;
|
|
top→ |
|
top→ |
|
top→ |
|
|
|||||||||||||||||
|
top→ |
调用A2前 |
调用A2后 |
调用A3后 |
返回A2后 |
top→ |
返回A1后 |
具体地,当调用(call)一个函数时,主调函数将声明中的参数表以逆序压栈,然后将当前的代码执行指针(eip)压栈,跳转到被调函数的入口点。
VarType Func (Arg1, Arg2, Arg3, ... ArgN)
{
VarType Var1, Var2, Var3, ...VarN;
//...
return VarN;
}
假设sizeof(VarType) = 4(DWORD), 则一次函数调用汇编代码示例为:
调用方代码:
push ArgN ; 依次逆序压入调用参数
push ...
push Arg1
call Func_Address ; 压入当前EIP后跳转(EIP:指令寄存器,extended instruction pointer,指向下一条等待执行的指令地址)
跳转至被调方代码:
push ebp ; 备份调用方EBP指针(EBP:基址指针,base pointer,指向系统栈最上面一个栈帧的底部)
mov ebp, esp ; 建立被调方栈底(ESP:堆栈指针,stack pointer,指向系统栈最上面一个栈帧的栈顶)
sub esp, N * 4; 为局部变量分配空间(栈是从高地址向低地址拓展,即栈顶在低地址处)
内存低地址 | ESP - - - - - - - - - - - - - - - - EBP - - - - - - - - - - - - - - - - - - - - - >| 内存高地址
mov dword ptr[esp - 4 * 1 ], 0 ; 初始化各个局部变量 = 0 这里假定VarType不是类
mov dword ptr[esp - 4 * ... ], 0
mov dword ptr[esp - 4 * N ], 0
. . . . . . ; 这里执行一些函数功能语句(比如将第N个参数[ebp + N * 4]存入局部变量), 功能完成后将函数返回值存至eax
add esp, N * 4 ; 销毁局部变量
mov esp, ebp ; 恢复主调方栈顶
pop ebp ; 恢复主调方栈底
ret ; 弹出EIP 返回主调方代码
接上面调用方代码:
add esp, N * 4 ; 释放参数空间, 恢复调用前的栈
mov dword ptr[ebp - 4], eax ; 将返回值保存进调用方的某个VarType型局部变量
(eax:4个字节;AX:eax的低2个字节;AH:AX的高字节;AL:AX的低字节)
C++内存的分区的更多相关文章
- Linux安装时内存如何分区的相关问题
Linux系统安装时内存如何分区:Linux系统必须的分区是根分区(/)和swap交换分区.普通用户一般分三个区,一个根分区(/),一个家目录(home分区),一个交换分区(swap分区),以80G的 ...
- C语言程序内存的分区
本文转载自:https://blog.csdn.net/shulianghan/article/details/20472269 C语言程序内存分配 (1) 内存分区状况 栈区 (stack) : ...
- jvm的内存空间分区
在方法(代码块)中定义一个变量时,java就在栈中为这个变量分配JVM内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的JVM内存空间:而在堆中分配的JVM内存由java虚拟机的自动 ...
- C++学习(5)—— 内存的分区模型
C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统进行管理的 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分配释放,存放函数的参数值.局部变量等 ...
- C/C++内存几大分区和存储空间的布局
先看一下可执行文件加载进内存后形成的进程在内存中的结构,如下图: 代码区:存放CPU执行的机器指令,代码区是可共享,并且是只读的. 数据区:存放已初始化的全局变量.静态变量(全局和局部).常量数据. ...
- [内存管理]linux内存管理 之 内存节点和内存分区
Linux支持多种硬件体系结构,因此Linux必须采用通用的方法来描述内存,以方便对内存进行管理.为此,Linux有了内存节点.内存区.页框的概念,这些概念也是一目了然的. 内存节点:主要依据CPU访 ...
- Eenterprise linux服务器分区
分区说明: (在MBR格式的硬盘下我会分/ /boot swap /data 四个分区,不建议在服务器上面使用LVM,中大型企业的IDC都是有存储区域的,专门管理硬盘容量的.)(分区的时候,请注意顺序 ...
- C 内存管理初步了解
1 首先变量了解几个概念 静态变量:用 static 修饰的变量 局部变量: 存储在栈区:作用域是函数块内:生存期是直到函数块结束 全局变量:存储在静态区:作用域是从定义到本源程序结束,生存期是运行期 ...
- C语言知识整理(3):内存管理(详细版)
在计算机系统,特别是嵌入式系统中,内存资源是非常有限的.尤其对于移动端开发者来说,硬件资源的限制使得其在程序设计中首要考虑的问题就是如何有效地管理内存资源.本文是作者在学习C语言内存管理的过程中做的一 ...
随机推荐
- JDK,JRE与JVM浅析
JAVA的两个特性: 1, 开源-指的是源代码免费 2,跨平台(可移植性好) 跨平台:是指跨操作系统 JVM(java virtual machine,java虚拟机) JVM就像是两国谈判时的使者充 ...
- SQL 查询表字段长度, 名称, 类型, 存储过程创建和修改时间
获取存储过程的修改时间和创建时间查询建立时间 --表 select * from sysobjects where id=object_id(N'表名') and xtype='U' --表的结构 s ...
- luogu P1036 选数 x
P1036 选数 题目描述 已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和.例如当 n=4,k=3,4 个整数分别 ...
- 为什么阿里巴巴要禁用Executors创建线程池?
作者:何甜甜在吗 juejin.im/post/5dc41c165188257bad4d9e69 看阿里巴巴开发手册并发编程这块有一条:线程池不允许使用Executors去创建,而是通过ThreadP ...
- div的文字倾斜
最近要写一个页面,需要一排文字是倾斜的,我就写了一下 <div class="qingx">倾斜导航</div> div.qingx{ -moz-trans ...
- 3D Computer Grapihcs Using OpenGL - 06 Vertex and Fragment Shaders
从这里就接触到了可编程图形渲染管线. 下面介绍使用Vertex Shader (顶点着色器)和 Fragment Shader(像素着色器)的方法. 我们的目标是使用这两个着色器给三角形填充绿色. 添 ...
- JavaScript异步编程助手:Promise模式
:Promises是一种令代码异步行为更加优雅的抽象,它很有可能是JavaScript的下一个编程范式,一个Promise即表示任务结果,无论该任务是否完成. 异步模式在Web编程中变得越来越重要,对 ...
- es之java索引操作
1.7.1: 创建索引 /** * 创建索引 * */ @Test public void createIndex(){ // 创建索引 CreateIndexResponse blog2 = cli ...
- int 和 字节 相互转换
In [10]: n = 0xf1f2 In [11]: bin(n) Out[11]: '0b1111000111110010' In [12]: n.bit_length() Out[12]: 1 ...
- 《图解 CSS3 核心技术与案例实战》
第一章 解开 CSS3 的面纱 使用 CSS3 的好处 减少开发和维护成本:如传统实现圆角边框需要绘图.切图才能完成,而使用 css 可以直接完成 提高页面性能 渐进增强(Progressive En ...