Есть ли способ избежать статического переполнения области памяти? - PullRequest
0 голосов
/ 12 марта 2012

Проблема очень очевидна, поэтому я просто покажу вам код:)

#include <stdio.h>
#include <string.h>
char *test1()
{
    static char c;
    char *p;
    p = &c;
    printf("p[%08x] : %s\n", (unsigned int)p, p);
    return p;
}

void *test2()
{
    static char i;
    char *buf;
    int counter = 0;
    for(buf = (char *)&i ; ;counter += 8)
    {
        memset(buf + counter, 0xff, 8);
        printf("write %d bytes to static area!\n", counter);
    }
}

int main()
{
    char *p;
    p = test1();
    strcpy(p, "lol i asd");
    p = test1();
    strcpy(p, "sunus again!");
    p = test1();
    strcpy(p, "sunus again! i am hacking this!!asdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
    p = test1();
    test2();
    return 0;
}

Сначала я написал test1(). Как видите, эти strcpy должны вызывать ошибку сегмента, потому что он явно обращается к недопустимой области памяти. Я знал основы статической переменной, но для меня это просто странно.

Тогда я написал test2(). наконец, это вызвало ошибку сегмента, после он записал почти 4 Кбайт.

Итак, мне интересно, как избежать возникновения такого рода ошибки (переполнение статической переменной)?

Почему я могу получить доступ к этим статическим областям памяти? Я знаю, что их нет ни в стеке, ни в куче.

PS. Возможно я не описываю свою проблему ясно. У меня есть несколько лет опыта программирования на С; Я знаю, что произойдет, когда это не статично. Теперь статика меняет почти все, и я хочу знать, почему.

Ответы [ 4 ]

1 голос
/ 12 марта 2012

Ошибка сегментации возникает, когда вы превышаете страницу памяти, которая составляет 4 КБ, поэтому, если повезет, вы можете написать полные 4 КБ до того, как это произойдет, и если следующая страница уже используется - даже это не гарантируется.Защитник стека Gcc может помочь иногда, но не в этом случае.Валгринд тоже может помочь.Ничто из этого не гарантировано.Ты лучше позаботься об этом сам.

1 голос
/ 12 марта 2012

Неопределенное поведение - это просто - undefined .Может показаться, что он работает, он может потерпеть крах, может украсть ваши деньги на обед.Только не делай этого.

0 голосов
/ 12 марта 2012

Вы избежите проблемы, зная, насколько велики ваши области памяти, и не пишите за пределами этих областей. Другого надежного способа решения этой проблемы не существует.

0 голосов
/ 12 марта 2012

Вы не можете избежать возможности перезаписи памяти, которую вы не выделяли в C.

Что касается способа сбоя ... Когда, где и как происходит сбой или неправильная работа вашего приложения, полностью зависит от вашего компилятора, флагов компилятора и памяти случайного состояния, которая была до того, как ваша программа начала выполняться. Вы обращаетесь к памяти, которую не должны, и в C совершенно не определено, как этот доступ повлияет на операционную среду.

Языки, которые управляют памятью (например, Java, C #), делают это за вас, но, конечно же, это стоит затрат на проверку границ.

Вы, безусловно, можете использовать библиотеки управления памятью (вместо malloc / free / new / delete), которые будут пытаться обнаружить неправильное управление памятью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...