码迷,mamicode.com
首页 > 其他好文 > 详细

关于C、内存、栈的一些杂谈

时间:2015-10-30 23:02:40      阅读:295      评论:0      收藏:0      [点我收藏+]

标签:

           c的程序要手动管理内存的,所有的数据(结构)都可以分为两种存储方式,连续存储,顾名思义申请一片连续的内存以供使用(数组、结构体、共用体、栈、队列);非连续存储,顾名思义断断续续的的存储,那有一点这有一点(链表,链表实现的树)。

          对齐填充,这个东西很有意思,看似无用其实很关键,比如有个结构体:

          struct xo { int i;char j,int k};

          结构体是连续存储的,我们设这个结构体起始地址为0x0,那么 i 的地址 就是 0x0 、j就是0x4、k就是0x5,可是呢OS(操作系统)不允许这样做,为什么呢?因为不好访问,windows就规定 k个字节数据的地址必须是k的整数倍,同理其他的OS也有类似规定,那么xo本来只占9字节,对齐填充之后就变成了12字节,也就是把j的1字节后面硬填了三个空白字节。这种对齐要求,在OS中比比皆是(尤其是在申请内存的时候,往往都是2、4、8的倍数)。

          栈帧结构,函数是通过栈来调用的,以栈帧为单位,当前函数就是栈顶帧,栈帧格式大概如下:

本地、临时变量表           
构造参数表
。。。。。一些东西
返回地址                   +4(偏移地址)
保存的%ebp             (这里是栈顶)

          栈是自高地址向低地址的,通过栈顶指针+偏移地址访问栈帧里的东西,栈帧的大小在调用函数(过程)的时候固定了(同样需要对齐),这也就可以解释为什么数组越界的后果非常严重了,函数中定义的数组一但越界,也就是说栈帧的大小不够了,装不下他了,那么他就会向上覆盖变量表、甚至上一帧的返回地址等等,使得程序不知所措甚至崩溃。

          同样栈帧的地址固定极容易被攻击,导致缓冲区泄露(想一想为什么呢?)   当然现在的OS都采取了各种办法随机化栈地址对栈进行保护。

 

关于C、内存、栈的一些杂谈

标签:

原文地址:http://www.cnblogs.com/liboyan/p/4924493.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!