缓冲区溢出 (vs) 缓冲区越界 (vs) 栈溢出

10
可能是重复问题:
什么是堆栈溢出和缓冲区溢出的区别?

缓冲区溢出和缓冲区越界的区别是什么?

缓冲区越界和堆栈溢出的区别是什么?

请提供代码示例。我查看了维基百科中的这些术语,但无法将其与C、C++或Java编程相匹配。


6
维基百科明确指出缓冲区溢出和缓冲区越界是同义词。因此,你的问题是你在https://dev59.com/wXNA5IYBdhLWcg3wBpDs上提出的问题的重复。 - innaM
1
这个问题可能只需要解决缓冲区溢出和缓冲区覆盖之间的区别(A:它们是同义词,表示相同的概念)。没有理由让维基百科成为信息来源,而不是SO。 - Yishai
缓冲区溢出是安全风险最常见的来源之一。缓冲区溢出实质上是由于将未经检查的外部输入视为可信数据而引起的。 - joe
@Kirsh,这也是缓冲区溢出的定义。 - Yishai
1
重复的内容,来自 https://dev59.com/wXNA5IYBdhLWcg3wBpDs。 - Steve Kuo
显示剩余2条评论
4个回答

42

将缓冲区视为仅仅是一个数组。人们常常混用“溢出”和“越界”这两个词,来描述当你尝试引用超出数组末尾的索引时,这是可以的。就我个人而言,我会有所区分:

缓冲区溢出是指当你尝试往数组中放入超过它本身容量的项时,它们会从缓冲区的末尾溢出。换句话说,这是由于写入操作导致的。

缓冲区越界是指在遍历缓冲区时,继续读取超出数组末尾的位置。你的迭代器正在遍历缓冲区并且持续前进。换句话说,这是由于读取操作导致的。

堆栈溢出则完全不同。大多数现代编程环境都是基于堆栈的,它们使用堆栈数据结构控制程序流程。每次调用函数时,一个新的项目被放置在程序的调用堆栈上。当函数返回时,项目从堆栈中弹出。当堆栈为空时,程序停止运行。问题在于,这个堆栈有一个限制大小。可能会一次性调用太多的函数,填满整个堆栈。此时就会出现堆栈溢出。最常见的做法是函数调用自身(递归)。


2
缓冲区溢出[...]来自读取 - 来源? - Paul
想要检查一下与@Paul相同引用的源代码。 - underthevoid
@underthevoid 这条信息很老了,但请回去仔细阅读我的第二和第三个句子。 - Joel Coehoorn
你的意思是它是你主观个人的区分吗? - underthevoid
@underthevoid 是的,但似乎大家都同意。 - Joel Coehoorn
今天再次吸引我的注意力,我决定进行一些小的编辑,其中之一强调了“个人”性质。 - Joel Coehoorn

18

缓冲区溢出/缓冲区覆盖:

void k()
{
    BYTE buf[5];
    for( int i = 0; i < 10; ++i )
        buf[i] = 0xcd;
}

Stackoverflow:

void f()
{
     int k = 0;
     f();
}

我找到了缓冲区运行的代码... 它实际上在做什么? - joe

1

在C/C++中,缓冲区溢出(buffer overflow)和缓冲区越界(buffer overrun)之间存在差异:

  • 我们可以将溢出定义为当你超过原始缓冲区大小进行索引/指针操作时(例如读取一个3元素数组的第6个元素)。
  • 我们可以将越界定义为当你有多个相邻的缓冲区,并且对第二个缓冲区进行索引操作时(例如读取第一个3元素数组的第6个元素,但实际上获取到了第二个3元素数组的第3个元素)。

堆栈溢出(stack overflow)有点类似于缓冲区溢出,当你填满整个堆栈“内存缓冲区”时会发生。


0
什么是缓冲区溢出和缓冲区越界的区别?我认为缓冲区溢出是指当您尝试在缓冲区末尾之外写入数据时,但您有一个检查来防止它。而缓冲区越界是指实际上在缓冲区末尾之外写入数据。前者是快速失败,后者则更难检测。
在Java中,您无法越界缓冲区,因为它始终具有边界检查,从而会产生BufferOverflowException异常。
缓冲区越界和堆栈溢出有什么区别?它们彼此没有任何关系。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接