LINUX.ORG.RU

[C] почему падает код ?

 


0

0

Объясните пожалуйста, почему падает программа:

int main(int argc, char **argv)
{
    char *s = "abcd";

    s[0] = 'e';

    return 0;
}

# gcc -o 1 1.c
# ./1
Segmentation fault

Если *s заменить на s[] - то работает. В чём разница ?
Спасибо.
anonymous

опять троль, что спрашивал про C# и т.д. ?

dimon555 ★★★★★
()

> В чём разница ?

перед вопросительным знаком нельзя ставить пробел

dilmah ★★★★★
()

Доходчиво.

В char *s = "abcd"; - инициализируется указатель на строку-константу.
Написав s[0], ты пытаешься записать в read only

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

сильно не пинайте, я только начал изучать самостоятельно... Спасибо за ответ, а в чём тогда разница char *s = "..." и char s[] = "..." ? Почему во втором случае код не падает ? Ещё раз спасибо.

anonymous
()
Ответ на: комментарий от anonymous

Потому что в char s[]="abcd" выделяется память под 4 символа и
завершающий нулевой символ '\0', а потом инициализируется строкой.
При использовании указателя память под массив символов не выделяется.
В этом различия.

ttnl ★★★★★
()

google rodata segment

svu ★★★★★
()

если в кратце изложить...

когда ты объявил char *abc = "asdf"

строка "asdf" попадает в .rodata, а переменной abc присваивается адрес расположения этой строки (т.е. адрес, находящийся в .rodata). это примерно то же самое, когда ты объявляешь переменную как const, вот для наглядности

const char abc[] = "asdf" <-- это попадет в .rodata
char *abc = "asdf" <-- это попадет в .rodata
char abc[] = "asdf" <-- это попадет в .data

посему, если ты пытаешься изменить что-то в .rodata, у тебя возникает сегфолт.

Deleted
()
Ответ на: комментарий от Deleted

Думаю, можно ещё проще, и даже не слишком обманывая.

char *s = "abcd" - это мы просим создать нам указатель. И затем указать им на "abcd".

char s[] = "abcd" - это мы просим создать нам массив char'ов. И затем заполнить его символами a,b,c,d,\0.

В первом случае нам никто не обещал ничего относительно доступа на сам "abcd". Как и, скажем, возможность создать NULL-указатель ещё не даёт нам права по этому указателю что-то записать.

alexsaa
()
Ответ на: комментарий от dilmah

если ты про sizeof, то он тоже будет одинаковый.

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.