程序栈

说到堆栈帧,你得先说说程序栈。

记忆功能程序堆栈区是支持操作,通常共享堆。

程序栈通常占领内存区域的下部,而堆用的是上部。

程序栈存放栈帧,栈帧有时候也称为活跃记录或活跃帧。栈帧存放函数參数和局部变量。堆存放动态内存。

调用函数时,函数的栈帧被推到栈上。栈向上长出一个栈帧。

当函数终止时,其栈帧从程序栈上弹出。

栈帧所使用的内存不会被清理,可是终于可能会被推到程序栈上的还有一个栈帧覆盖。

动态分配的内存来自堆。堆向下生长。随着内存的分配与释放。堆中会布满碎片。

虽然堆是向下生长的,可是这仅仅是大体方向,实际内存可能位于堆上的任何位置。

栈帧的组织

栈帧由以下几个元素组成:

    返回地址:函数完毕后要返回的程序内部地址
   局部数据存储:为局部变量分配的内存
   參数存储:为函数參数分配的内存
   栈指针和基指针:执行时系统用来管理栈的指针   

栈指针通常指向栈顶部。基指针通常存在并指向栈帧内部的地址,比方返回地址,用来协调訪问栈帧内部的元素。

这两个指针都不是C指针,他们是执行时系统管理程序栈的地址。

以下这个函数给出实例:

float average(int *arr, int size){
int sum;
printf("arr: %p\n",&arr);
printf("size: %p\n",&size);
priintf("sum: %p\n",&sum); for(int i = 0;i < size;i ++){
sum +=arr[i];
} return (sum *1.0f) / size;
} //output
//arr: 0x500
//size: 0x504
//sum: 0x480

当中參数地址和局部变量之间的空档。保存的是执行时系统管理栈所需的其它栈帧元素。

系统在创建栈帧时,将參数以跟声明时相反的顺序推到栈上,最后推入局部变量。在这个样例中,size在arr之后被推入。通常,接下来会推入函数调用的返回地址。然后是局部变量。推入它们的顺序和在代码中的顺序相反!

从原理上说,本例中的栈向上生长。只是栈帧的參数和局部变量以及新栈帧被加入到了低内存地址。

栈的实际生长方向和实际相关。

for语句中的i没有包括在栈帧中。这是由于C语言中把块语句当成“微型”函数。

将栈帧推到程序栈上时,系统可能会耗尽内存,这样的情况叫做栈溢出,一般会导致程序非正常终止。要牢记住每个线程都有自己的程序栈,一个或多个线程访问存储器中的同一个对象可能会造成冲突。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

堆栈帧的组织——C/C++内存管理必须掌握的更多相关文章

  1. 深入C#内存管理来分析值类型&引用类型,装箱&拆箱,堆栈几个概念组合之间的区别

    C#初学者经常被问的几道辨析题,值类型与引用类型,装箱与拆箱,堆栈,这几个概念组合之间区别,看完此篇应该可以解惑. 俗话说,用思想编程的是文艺程序猿,用经验编程的是普通程序猿,用复制粘贴编程的是2B程 ...

  2. C++ 内存管理与堆栈

    /*内存管理与堆栈: * # 一个由C/C++编译的程序占用的内存分为以下几个部分 * 1.栈区:由编译器自动分配释放,数据先进后出 * 2.堆区:由程序员手动分配释放,数据先进先出, * new 和 ...

  3. JMM内存管理

    原文地址http://www.cnblogs.com/BangQ/p/4045954.html 原本准备把内存模型单独放到某一篇文章的某个章节里面讲解,后来查阅了国外很多文档才发现其实JVM内存模型的 ...

  4. How Javascript works (Javascript工作原理) (三) 内存管理及如何处理 4 类常见的内存泄漏问题

    个人总结: 1.两种垃圾回收机制: 1)引用标记算法:如果检测到一个对象没有被引用了,就清除它. ***这种算法不能处理循环引用的情况*** 2)标记—清除算法:从根(全局变量)开始向后代变量检测,任 ...

  5. JavaScript 工作原理之三-内存管理及如何处理 4 类常见的内存泄漏问题(译)

    原文请查阅这里,本文有进行删减,文后增了些经验总结. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第三章. 我们将会讨论日常使用中另一个被开发者越来越忽略的 ...

  6. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...

  7. 深入了解C#系列:谈谈C#中垃圾回收与内存管理机制

    今天抽空来讨论一下.Net的垃圾回收与内存管理机制,也算是完成上个<WCF分布式开发必备知识>系列后的一次休息吧.以前被别人面试的时候问过我GC工作原理的问题,我现在面试新人的时候偶尔也会 ...

  8. 简单的例子 关于Java内存管理的讲解

    我想做的是,逐行读取文件,然后用该行的电影名去获取电影信息.因为源文件较大,readlines()不能完全读取所有电影名,所以我们逐行读取. 就这段代码,我想要在位置二处使用base64,然后结果呢? ...

  9. Erlang 虚拟机 BEAM 指令集之内存管理相关的指令

    翻看 BEAM 虚拟机指令集的时候(在编译器源码目录下:lib/compiler/src/genop.tab),会发现有一些和内存分配/解除分配相关的指令,如下所示: allocate StackNe ...

随机推荐

  1. Delphi的DLL里如何实现定时器功能?

    一,首先引入“mmsystem”单元. 二,启动定时器: var MMTimerID: Integer; // 定时器ID MMTimerID := timeSetEvent(1000, 0, @Ti ...

  2. Scanner类及正则表达式

    import java.util.Scanner; public class ScannerToString { public static void main(String[] args) { Sc ...

  3. JavaScript函数节流与函数去抖

    介绍 首先解释一下这两个概念: 函数节流(throttle):是让一个函数无法在很短的时间间隔内连续调用,当上一次函数执行后过了规定的时间间隔,才能进行下一次该函数的调用. 函数去抖(debounce ...

  4. Linux学习记录--匿名沟通渠道

    匿名沟通渠道 管道Linux最初支持Unix IPC其中的一种形式.具有下列特征: 1.管道是半双工.数据可以仅在一个方向流动:当双方需要沟通.建设两条管线需要. 2.仅仅能用于父子进程或者兄弟进程之 ...

  5. Eclipse在点击运行后不能自动保存的解决

    今天在eclipse上写程序调试时,发现当我点击运行按键之后,并不能在运行前帮我自动保存,也就是说每次修改代码之后, 运行的还是前一次运行之前的代码,并不是修改之后的代码,因此通过在网上搜索解决方案之 ...

  6. Java反射机制的使用方法

    Java的反射机制同意你在程序执行的过程中获取类定义的细节.有时候在程序执行的时候才得知要调用哪个方法,这时候反射机制就派上用场了. 获取类 类的获取方法有下面几种: forName().通过Clas ...

  7. AIR

    There is a meaning for wings that cannot fly,it's a previous memory of when you once flew through th ...

  8. Servlet API中文版

    基本类和接口 一.javax.servlet.Servlet接口 servlet抽象集是javax.servlet.Servlet接口,它规定了必须由Servlet类实现由servlet引擎识别和管理 ...

  9. VS2010使用静态编译的qt库

    Qt开发界面很方便,但发布程序就不那么方便了,你的把引用到的dll一起发布才行,要是能静态编译就好了,发布的时候只有一个exe多方便. 虽然以前为了方便,直接安装的qt-windows-opensou ...

  10. TControl的消息覆盖函数大全(15个WM_函数和17个CM_函数,它的WndProc就处理鼠标与键盘消息)

    注意,这些函数只有Private一种形式(也就是不允许覆盖,但仍在动态表格中)(特别注意,这里居然没有WM_PAINT函数): TControl = class(TComponent) private ...