代码分析栈(stack)的生长方向
1.1背景
以前搞C++的时候,由于没有搞过什么底层逻辑,虽然对堆栈有所了解,但仍停留在表面。今天通过探索下堆栈的生长方向。
**栈:**由编译器在需要的时候分配,在不需要的时候自动清除的变量存储区。里面通常是局部变量,函数参数等。
**堆:**由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
**自由存储区:**由malloc等分配的内存块,和堆十分相似,不过它使用free来结束自己的生命。
**全局/静态存储区:**全局变量和静态变量被分配到同一块内存中,在以前的c语言中。全局变量又分为初始化的和未初始化的,在c++里面没有这个区分了,他们共同占用同一块内存。
查了些资料,有说向上生长,也说向下生长。
另外关于函数参数压栈,也有描述从右往左压栈,这些方向性的描述是什么意思?
1.2代码实例
#include <stdio.h>
#include <string.h>
void test_example(int a,int b,int c){int arr[2] = {1,2};int d = 0;int e = 0;printf("a:%d a_ptr: %p, b: %d b_ptr: %p, c: %d c_ptr: %p \n",a,&a,b,&b,c,&c);printf("d: %d d_ptr:%p , e: %d, e_ptr: %p \n",d,&d,e,&e);printf("arr: %p \n",arr);memcpy(&e,arr,sizeof(arr));printf("c: %d c_ptr: %p, d: %d e: %d ",c,&c,d,e); }int main(){int a = 3;int b = 4;int c = 5; printf("Hello World \n");test_example(a,b,c);return 0;
}
代码中,很容易发现memcpy copy越界,e
只有4bytes,被写越界4个字节。
我们不在这里讨论为什么写越界的问题。你知道写穿的这4个字节影响性吗?或者说覆盖了谁吗?
我们先看下linux操作系统下,gcc编译后运行结果:
可以看到d = 2
,栈中d这块内存被覆盖了,证明在栈中d位于高地址,e位于低地址,实际打印也如下图所示。
同样一块代码,在windons系统下运行,如图:
函数参数和局部变量在内存中的位置如上图。
1.3总结
到这我们一直没有解释上下箭头是什么意思。
- 1、内存没有方向的概念,只有高低的区别。
- 2、如果压栈的顺序是从低地址往高低地址依次压栈,则是向上生长。
高地址往低地址依次压栈,则是向下生长。
这里其实有个潜台词,要先确定栈底位置,比如linux,一块栈内存,栈底位于低地址,所以压栈是从低地址往上增长。windows,栈底则位于高地址。 - 3、关于函数参数,从右往左压栈没有问题,比如我们例子中的c–>b–>a从栈低依次压栈。
- 4、关于局部变量,其实也有规律,linux平台是先定义,后入栈。Windows,则是先定义,先入栈。
有了如上认识,我们就可以,当遇到踩内存踩了谁的问题时候,就有了初步分析。
栈的生长方向不同平台不一样,以及一些书籍也是基于某一个平台给出的描述,不能说是错,试着了解下你工作中的栈呢。
代码分析栈(stack)的生长方向相关推荐
- python数据结构和算法 时间复杂度分析 乱序单词检测 线性数据结构 栈stack 字符匹配 表达式求值 queue队列 链表 递归 动态规划 排序和搜索 树 图
python数据结构和算法 参考 本文github 计算机科学是解决问题的研究.计算机科学使用抽象作为表示过程和数据的工具.抽象的数据类型允许程序员通过隐藏数据的细节来管理问题领域的复杂性.Pytho ...
- 一文搞懂栈(stack)、堆(heap)、单片机裸机内存管理malloc
大家好,我是无际. 有一周没水文了,俗话说夜路走多了难免遇到鬼. 最近就被一个热心网友喷了. 说我的文章没啥营养,所以今天来一篇烧脑的. 哈哈,开个玩笑,不要脸就没人能把我绑架. 主要是最近研发第二代 ...
- u-boot分析之两阶段代码分析(三)
目录 u-boot(三)启动文件 1,概述 2,uboot第一阶段代码分析: 汇编 2,uboot第二阶段代码分析 C:_start_armboot C:main_loop u-boot(三)启动文件 ...
- 一个简单的时间片轮转多道程序内核代码分析
郑斌 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 第二周的实验内容分析 1. ...
- Pixhawk代码分析-启动代码及入口函数
启动代码及入口函数 基础知识 关于坐标系 1)GeographicCoordinate System Represents position on earth with alongitude and ...
- 数据结构括号匹配代码_栈:如何实现有效括号的判断?
点击上方蓝字,关注:无量测试之道 作者 | 无量测试之道 编辑 | 小 晴有效括号,刷过LeetCode的也许对这道题很熟悉. 1.开篇问题:有效的括号[1] 假如现在要你来解这道题 ...
- java栈顶元素_栈(Stack)
栈(Stack)是一种后进先出的数据结构(LIFO:last in first out),只允许访问栈中的第一个数据项:即最后插入的数据项.移除这个数据项之后,才能看到第二个数据项,以此类推. 往栈中 ...
- 有向图的强连通分量--Tarjan算法---代码分析
本文就是做个代码分析,顺便说下理解. 一.预备知识: 需要知道什么是: 回边.前向边.交叉边 二.上代码: #include<algorithm> #define NIL -1using ...
- 反汇编代码分析--函数调用
C++反汇编代码分析--函数调用 代码如下: #include "stdlib.h" int sum(int a,int b,int m,int n) { return a+b ...
最新文章
- java查询结果自定义显示_JPA自定义对象接收查询结果集操作
- python空列表添加_Python列表的简单操作
- 校门外的树(洛谷-P1047)
- ICCV 2019丨基于跨视角信息融合的三维人体姿态估计
- 自动化测试--实现一套完全解耦的测试框架(三)
- Xcode安装及卸载
- 答应我,别再靠!= null走天下了可以吗?
- 纯Qt版中国象棋:实现双人对战、人机对战及网络对战
- 浪潮服务器销售案例ppt,浪潮服务器产品线介绍(ppt 105页)
- 极光:2019年个人网盘行业研究报告
- flog和flag_立flag是什么梗 立个flag是什么意思
- Python实战题 · 计算圆面积
- 电脑开机一直自动重启
- 对链表进行插入排序。从第一个元素开始,该链表可以被认为已经部分排序。每次迭代时,从输入数据中移除一个元素,并原地将其插入到已排好序的链表中。
- 狼图腾--满族为什么能以少统多
- 【转】plt.plot的颜色
- 基于Dragonboard 410c设计的智能管家
- image失败 安装scikit_安装SciKitImage错误127
- java 不是内部或外部命令,也不是可运行程序
- 【苹果推信iMessage】群发安装软件sent with Invisible Ink“设置”应用