Статические глобальные переменные против глобальных переменных 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()
Вы также можете взглянуть на документацию, в которой четко указано, что в него включен нулевой символ.