Operating system 堆栈与缓冲区

Operating system 堆栈与缓冲区,operating-system,terminology,Operating System,Terminology,缓冲区和堆栈之间的区别是什么?缓冲区溢出和堆栈溢出是一回事吗 谢谢。堆栈溢出通常是由不受约束的递归引起的(尽管如果没有足够的堆栈空间进行正常级别的函数调用,例如嵌入式系统,或者如果限制太高,甚至使用有限的递归,则在正常的事件过程中也会导致堆栈溢出)。下面是一个例子: void f (void) { f(); } int main (void) { f(); return 0; } 在该示例中,f()函数非常愚蠢地调用自己,每次调用时,它都会分配一个堆栈帧,这最终会导致堆

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


谢谢。

堆栈溢出通常是由不受约束的递归引起的(尽管如果没有足够的堆栈空间进行正常级别的函数调用,例如嵌入式系统,或者如果限制太高,甚至使用有限的递归,则在正常的事件过程中也会导致堆栈溢出)。下面是一个例子:

void f (void) {
    f();
}
int main (void) {
    f();
    return 0;
}
在该示例中,
f()
函数非常愚蠢地调用自己,每次调用时,它都会分配一个堆栈帧,这最终会导致堆栈溢出

另一方面,缓冲区溢出是由于写入超出缓冲区末尾而导致的。它们经常被混淆,因为堆栈上的缓冲区溢出通常会损坏堆栈,但从技术上讲,它们是完全不同的东西。基于堆栈的缓冲区溢出的一个示例是:

void f (void) {
    char str[10];
    strcpy (str, "This is far too long to fit");
}
这可能会损坏堆栈,因为您试图将27个字符(28个字节)的字符串推入一个只有10个字节大小的空间

但是缓冲区溢出不一定要在堆栈上。如果缓冲区是从堆中分配的(例如,使用
malloc
),则很有可能会将内存区域变成垃圾,如下所示:

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

与前面的示例类似,只是缓冲区溢出不会损坏堆栈。相反,它是在堆中的缓冲区结尾之外写入的。

缓冲区溢出是指您没有检查缓冲区的长度,或者没有将未终止的缓冲区传递给预期的函数(特别是在C中)。您将通过分配的缓冲区的末尾

缓冲区溢出:

char *foo = malloc(10); /* 10 bytes in our buffer */
char bar[] = "This is way bigger than 10 bytes"; 
strcpy(foo, bar);
int foo()
{
    int bar = 4;
    foo();
    return 1; /* we never get here, silly */
}
堆栈溢出是指耗尽所有堆栈内存。这是通过递归调用的,在堆栈上分配太多的东西

堆栈溢出:

char *foo = malloc(10); /* 10 bytes in our buffer */
char bar[] = "This is way bigger than 10 bytes"; 
strcpy(foo, bar);
int foo()
{
    int bar = 4;
    foo();
    return 1; /* we never get here, silly */
}