堆栈与缓冲区

Far*_*naz 4 operating-system terminology

缓冲区和堆栈有什么区别?缓冲区溢出和堆栈溢出是一回事吗?

谢谢.

pax*_*blo 9

堆栈溢出通常是由无限制的递归引起的(尽管如果没有足够的堆栈空间用于正常级别的函数调用,例如嵌入式系统,或者即使递归有限,也可能在正常的事件过程中引起)限制太高了).以下示例:

void f (void) {
    f();
}
int main (void) {
    f();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在该示例中,该f()函数非常愚蠢地调用自身,并且每次执行该操作时,它都会分配堆栈帧,这最终会导致堆栈溢出.

另一方面,缓冲区溢出是由超出缓冲区末尾的写入引起的.它们经常被混淆,因为堆栈上的缓冲区溢出通常会破坏堆栈,但从技术上讲,它们是非常不同的东西.基于堆栈的缓冲区溢出的示例是:

void f (void) {
    char str[10];
    strcpy (str, "This is far too long to fit");
}
Run Code Online (Sandbox Code Playgroud)

这可能会破坏堆栈,因为你试图将一个27个字符的字符串(28个字节)推入一个只有10个字节大小的空间.

但是缓冲区溢出不一定必须在堆栈上.如果缓冲区是从堆中分配的(例如,有malloc),那么它很可能会丢弃内存竞技场,如下所示:

void f (void) {
    char *blk = malloc (10);
    if (blk != 0) {
        memset (blk, ' ', 100);
        free (blk);
    }
}
Run Code Online (Sandbox Code Playgroud)

与前面的示例类似,但缓冲区溢出不会破坏堆栈.而是在堆中缓冲区的末尾写入.