Статические глобальные переменные против глобальных переменных C

У меня есть программа ниже. Если я объявляю переменные a, b, c статическими глобальными переменными, это вызывает ошибку сегментации, но если я объявляю их нестатическими глобальными или локальными переменными, это не дает ошибки сегментации. Почему так себя ведет? Я знаю, что существует больше данных, чем могут хранить переменные, но почему он выдает ошибку seg, когда только объявлена ​​статическая ошибка? Хранятся ли статически объявленные переменные в какой-то другой части стекового фрейма, где перезапись не разрешена?

РЕДАКТИРОВАТЬ: я знаю, что strcpy не является безопасным. Но это не моя проблема. Я хочу понять, почему одно переполнение дает segfault, а другое переполнение может не дать segfault.

#include<stdio.h>
#include<string.h>

static char a[16];
static char b[16];
static char c[32];

int main(int argc, char *argv[]){

// char a[16];
 //char b[16];
 //char c[32];
    strcpy(a,"0123456789abcdef");
    strcpy(b,"0123456789abcdef");
    strcpy(c,a);
    strcpy(c,b);
    printf("a = %s\n",a);
    return 0;
}

2 ответа

Решение

Выравнивание памяти имеет значение в переменной стека. Попробуйте это с -fstack-protector-strong или аналогичной опцией защиты стека, вы увидите сбой. Также объявите int после c и переполните ваш массив c, вы можете увидеть сбой. Вы должны убедиться, что там нет отступов. поскольку b является массивом, все, что вы переполняете из 'a', переходит к b. Попробуйте что-то вроде:

struct foo {
        char c[10];
        int x;
    } __attribute__((packed));

вы увидите сбой при переполнении c.

Вы сталкиваетесь с неопределенным поведением при переполнении.

Обратите внимание, что строка const char * в C всегда заканчивается на 0, что означает, что строка "0123456789abcdef" на самом деле состоит из 17 символов: "0123456789abcdef\0"

Я предлагаю вам всегда использовать безопасную версию

strncpy() 

Вы также можете взглянуть на документацию, в которой четко указано, что в него включен нулевой символ.

http://www.cplusplus.com/reference/cstring/strcpy/

Другие вопросы по тегам