堆栈缓冲区溢出,堆栈下溢和堆栈溢出之间有什么区别?

问题描述 投票:0回答:2

我的数据结构老师在我们今天的课堂上学习堆栈时提到了它,但没有给出正确的解释。

data-structures programming-languages stack-overflow buffer-overflow
2个回答
2
投票

首先,堆栈和缓冲区是您可能知道的不同的东西。

当程序(任何类型)尝试写入超出其分配的内存时,会发生缓冲区溢出。想像

int myArray[5];
myArray[9]=3;

堆栈溢出是一种特殊情况。在运行时,例如递归函数,已经预订的堆栈会不断增长,大于原始预留!

void recurse()
{
int numbers[20000];
    recurse();
}

这将永远不会结束。每个函数调用都会创建一个新的堆栈帧,并且堆栈最终将消耗比为其保留的内存更多的内存。

查看this了解更多详情!

而堆栈下溢则类似于缓冲区溢出。通过这个例子,你会理解它!

想象一下,你有一个列表,你正在弹出元素。

我假设你知道弹跳是什么,但如果你还没有在你的主题中做到这一点,它基本上是取出元素。根据结构的类型,它将从一侧或另一侧带走它们!

想象一下名为Listcon的三个数字列表:[1,2,3]。我会这样写:List => [1,2,3]这意味着“List包含[1,2,3]”。

List => [1,2,3]
List.pop => [2,3] //List.pop now contains (->) [2,3]
List.pop => [3]
List.pop => []
List.pop => ??? Stack underflow!

2
投票

缓冲区溢出是一个非常通用的术语,用于描述一种情况,在该情况下,缓冲区中填充的元素多于应有的元素,从而导致未定义的行为。想象一下,你有一个1024字节的数组,从网络读取1kb,你试图在其中放置更多。

调用堆栈溢出是一种情况,其中有太多的函数调用(通常在你有无限递归时发生),正是由于它们的数量,计算机往往耗尽内存以分配太多的堆栈帧(想象每一个)堆栈框架有一个默认大小,默认情况下在linux中大约2MB iirc - 如果你得到一个调用堆栈树数千个函数深度,你可能会耗尽内存)。

© www.soinside.com 2019 - 2024. All rights reserved.