堆栈缓冲区溢出、堆栈下溢和堆栈溢出有什么区别?

What is the difference between stack buffer overflow, stack underflow and stack overflow?

我的数据结构老师在我们今天学习堆栈的讲座中提到了它,但没有给出适当的解释。

缓冲区溢出是一个非常通用的术语,描述了缓冲区中填充的元素多于应有的元素,从而导致未定义行为的情况。 想象一下,您有一个 1024 字节的数组,要从网络读取 1kb,然后您尝试将更多内容放入其中。

调用堆栈溢出是一种函数调用过多的情况(通常发生在无限递归时),正是因为它们的数量,计算机往往 运行 内存不足用于分配太多的堆栈帧(假设每个堆栈帧都有一个默认大小,默认情况下 linux 中大约 2MB iirc - 如果你得到一个调用堆栈树,有数千个函数,你可能会 运行内存)。

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

缓冲区溢出 发生在程序(任何类型)试图写入超出其分配的内存时。想象一下

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

堆栈溢出是一个特例。当运行,比如一个递归函数,已经有预留的栈,一直增长到比原来的预留更大!

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

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

查看this了解更多详情!

stack underflow类似buffer overflow。看了这个例子你就明白了!

假设您有一个列表,并且正在弹出元素。

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

假设一个名为 List 的列表包含三个数字:[1,2,3]。我会这样写:List => [1,2,3] 意思是 "List contains [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!