стек против буфера - PullRequest
       22

стек против буфера

4 голосов
/ 14 марта 2011

В чем разница между буфером и стеком?Переполнение буфера и переполнение стека - это одно и то же?

Спасибо.

Ответы [ 2 ]

9 голосов
/ 14 марта 2011

Переполнение стека обычно вызывается необузданной рекурсией (хотя это может быть вызвано обычным ходом событий, если у вас недостаточно стекового пространства для нормального уровня вызовов функций, например, во встроенных системах или даже при ограниченная рекурсия, если пределы слишком высоки). Пример ниже:

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);
    }
}

Аналогично предыдущему примеру, за исключением того, что переполнение буфера не приводит к повреждению стека. Скорее он пишет за пределами буфера в куче.

2 голосов
/ 14 марта 2011

Переполнение буфера - это когда вы не проверяете длину буфера или не передаете незавершенный буфер функции, ожидающей его (особенно в 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 */
}
...