探讨程序编程中栈空间的本质以及缓冲区溢出的问题

编程过程中的内存分布

在讲文明栈空间之前我们先来回顾一下我们之前讲到的内存分布,我们看一下下面的分布图

栈空间的最大值是多少?

在外面常用的Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域,它的起始位置和大小时系统固定好的,在Windows中栈的大小时2MB,在Linux中默认栈空间的大小是8MB,可以说很小,为什么说很小的,我们堆空间比它大的太多了一般在2G左右。

栈的性质

昨天讲的关于计算机存储的文章我们知道我们内存的读取速度是比硬盘快得,当我们与到需要大量读取数据或者是说需要频繁的去存储和取出时,我们开辟一块大的内存空间是能够很好的提高我们程序的运行效率,但是我们知道速度越快意味着他空间越小。

栈和堆的区别

我们的栈在内存 是连续的向低内存扩展的空间,使用的申请与释放都是由系统自动完成。但是我们的堆空间必须是手动申请和手动释放,这就导致了堆空间的使用容易造成内存的泄露问题。在编写代码中一定一定要注意这个问题。内存泄露对系统和程序来说都是致命的。

栈内存大小可以改变么?

我查了相关资料给的答案是可以通过一些设置来改变栈空间的大小:

一、link(链接)时用/STACK指定它的大小,或者在.def中使用STACKSIZE指定它的大小。

二、使用控制台命令:“EDITBIN”更改exe的栈空间大小。

在Linux系统中可以使用命令ulimit—s来设置。感兴趣的读者可以自己去试试,这里就不做展示了,因为我们还要学一个更重要的知识。

缓冲区溢出

缓冲区是我们程序在运行的时候内存中一个连续的地址,里面存放了一些程序运行需要数据,那什么是缓冲区溢出呢?通俗一点说就是装的太多溢出来, 就像你用水杯去接水,如果水杯满了你还在继续装水就会流出来,这就是溢出。我们缓冲区溢出呢就是填充到缓冲区的数据超过自身的限制时发生溢出的数据覆盖其他的合法数据,举一个例子一个

int[3];

char b;

你给赋值时1,2,3,4,这时候就会发生溢出每一处的后果可能就是把后面的b覆盖了,导致b编程了溢出的4,当然这个例子也不是很恰当,为什么呢,因为我们还要看一下 我们是不是连续的内存空间,但是你大概懂这意思就好了。

代码模拟

在该程序中我们定义了一个buff[4],然后给他赋值,我们可以很容易看出来主程序没有防止越界的的措施,那如果输入的内容超出4个就会发生溢出,如果小于等于4个是不存在溢出的,我们来看一下下面的执行结果

结果分析

正常的赋值没有越界的时候内存存储情况是这样的,然后我们在看看如果输入的内容超过四个的的话发生溢出时内存地址结构是什么样的。

我们可以看得出来原来的一些数据内覆盖成A了,这会导致什么样的结果呢,如果被覆盖的数据很重要,那可能会导致程序运行失败,人恒过再是更重要的数据被覆盖,可能会导致系统的崩溃。很多网络攻击者如果发现系统存在这种漏洞,加以利用那对我们的系统将会是致命的,防止缓冲区的溢出,关键就在于我们程序开发者在开发的时候仔细检查溢出的情况,不允许数据溢出缓冲区!

关注我每天写一点技术!让我们离自己的梦想更进一步!!

相关文章