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语言内存管理的过程中做的一 ...
随机推荐
- ASP.NET上传一个文件夹
之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...
- 博弈论 x
——关于博弈论 四道例题带你走进博弈论~ (考虑必败态,必胜态) Ps:要理解这种思想,首先要明白什么叫必败态.说简单点,必败态就是“在对方使用最优策略时,无论做出什么决策都会导致失败的局面”.其他的 ...
- c++复习——类(2)
1.this指针 this指针是一个指向对象的指针. this指针是一个隐含于成员函数中的对象指针. this指针是一个指向正在调用成员函数的对象的指针. 类的静态成员函数没有this指针 ...
- R 动态定义变量名 assign
rm(list=ls()) library(GSVA) library(GSEABase) library(GSVAdata) library(msigdbr) library(org.Hs.eg.d ...
- Educational Codeforces Round 16 E. Generate a String (DP)
Generate a String 题目链接: http://codeforces.com/contest/710/problem/E Description zscoder wants to gen ...
- package.json保存
# 确保已经进入项目目录 # 确定已经有 package.json,没有就通过 npm init # 创建,直接一路回车就好,后面再来详细说里面的内容. # 安装 webpack 依赖 npm ins ...
- 转载自:StringUtils的常见方法
转载自:https://blog.csdn.net/simple_smile_sun/article/details/51819158 注:运用StringUtils需要导入相关jar文件,commo ...
- Fabric基础架构原理(二)
Fabric 的网络节点本质上是互相复制的状态机,节点之间需要保持相同的账本状态.为了实现这个目的,各个节点需要通过共识( consensus )过程,对账本状态的变化达成一致性的认同. Fabric ...
- XML的基础之一(概念和语法)
XML的基础(概念和语法) xml html 概念 异同 XML全称为extensible markup language,即可扩展标记语言,简单理解为可预定义标签的编程语言.它与HTML(超文本标 ...
- 【HTML】<!DOCTYPE html>作用
1.定义: DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档. <!DOCTYPE> 声明 ...