2010-11-08 4 views
4

Я использовал эту строку кода многократно (обновление: когда строка была параметром функции!), Однако, когда я пытаюсь это сделать, теперь я получаю шину ошибка (как с gcc, так и с clang). Я воспроизвожу простейший возможный код;Ошибка шины при попытке доступа к символу в строке в C

char *string = "this is a string"; 
char *p = string; 
p++; 
*p='x'; //this line will cause the Bus error 
printf("string is %s\n",string); 

Почему я не могу изменить второй символ строки с помощью p-указателя?

+1

В gcc есть опция '-Wwrite-strings', которая предупредит вас об изменении строковых букв, сделав их' const char [] '. Имейте в виду, что в стандарте указано, что буквальные строки - это 'char []' ("' только для чтения char [] '", но не 'const'), а их' const' делает ваш компилятор (более) несоответствующим. – pmg

ответ

9

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

char str[] = "This is a string"; 
str[0] = 'S'; /* works */ 

Я использовал эту строку кода много раз ..

Я уверен, надеюсь, что нет. В лучшем случае вы получите segfault (я говорю «в лучшем случае», потому что попытка изменить память readonly - это неуказанное поведение, и в этом случае что-то может произойти, и авария - лучшая вещь, которая может произойти).

Когда вы объявляете указатель на строковый литерал, он указывает на память только для чтения в сегменте данных (посмотрите на сборку, если хотите). Объявление вашего типа как char [] будет копировать этот литерал в стек функции, что, в свою очередь, позволит его модифицировать при необходимости.

+1

+1. Попытка изменить строковый литерал - это неопределенное поведение. Возможно, это работает, но, конечно же, это не гарантируется. – dreamlax

+0

«В лучшем случае вы получите segfault» - на самом деле, этот бит не совсем прав. Неопределенное поведение не определено, а когда-то это означает, что он работает так, как ожидалось :-) Существует множество встроенных микросхем без защиты памяти. Не говорите, что ваш _answer_ ошибочен, так как вопрос помечен как linux (так что +1 для этого), просто один конкретный момент не обязательно является истинным во всех случаях. – paxdiablo

+0

@paxdiablo: Следовательно, часть «В лучшем случае» =) –