2013-04-10 3 views
2

В C++, почему компилятор не позволяет изменять следующий указатель символов следующим образомдоступа символ указателя

#include <iostream> 

int main() 
{ 
char* cp = "overflow"; 
cp[1]='p'; 
return 0; 
} 

Выход: сбой во время выполнения.

но массив символов позволяет,

#include <iostream> 

int main() 
{ 
char cps[] = "overflow"; 
cp[1]='p'; // this compiles fine and output is operflow 
return 0; 
} 

просто хочу знать, что происходит во время выполнения, и почему это происходит сбой. Спасибо.

+1

'char cps =" overflow ";' просто неправильно, вы имели в виду 'char cps [] =" overflow ";'? – unwind

+0

@unwind извините, так или иначе это пропало без вести. исправлено .. –

ответ

9

Строковые литералы являются значениями типа char const[], где важна важная часть const. Попытка изменить объект, тип которого const, составляет Неопределенное поведение.

в соответствии с пунктом 2.14.5/8 C++ 11 стандарта на:

Обычные строковых литералов и UTF-8 строковых литералов также называют узкими строковых литералов. узкая строковый литерал имеет тип «массив нconst char», где п является размер строки, как определено ниже, и имеет статический срок хранения (3.7).

Во втором случае (предположит, что ваш означало char cps[] = "overflow";, в квадратных скобках), вы инициализация не- constкопию строки буквальной. Изменение этой копии в порядке.

Также обратите внимание, что преобразование из строки литерала, не -constchar * является устаревшим в C++ 03 и нелегального в C++ 11. Это, с другой стороны, является законным:

char const* cp = "overflow"; 
// ^^^^^ 
+0

Должно быть, по крайней мере, предупреждение для большинства компиляторов, даже pre-C++ 11? – drquicksilver

+0

@drquicksilver: есть на GCC, при условии, что вы повышаете уровень предупреждения достаточно. – ereOn

+0

@ Энди, почему он рассматривается как char const [], любая действительная причина этого? –

2

Это: char* str="";, является строковым и может храниться в разделе только для чтения памяти, следовательно, может произойти сбой. Используйте const char* const str="string"; (как указатель и данные являются постоянными или по крайней мере данные должны быть постоянными: const char* str="string"; или char const* str="string";)

Если вы попытаетесь изменить содержимое строкового литерала это неопределенное поведение и ошибки сегментации в результате аварии может произойти ,

0

Когда вы устанавливаете char* cp = "overflow";, вы создаете блок памяти только для чтения, содержащий "overflow" (за которым следует завершающий байт NULL), поэтому вы не можете писать там. Попытка изменить c[x] требует написания там.

Что касается вашего второго блока кода - чего-то не хватает, так что часть вопроса неясна.

0

Поскольку указатель на символ не является array и low-level const. Вы могли бы сделать

char cp[] = {'o', 'v', 'e', 'r', 'f', 'l', 'o', 'w', '\0'}; 

char *pcp = cp; 

*++pcp = 'p'; 

Однако "overflow" постоянная последовательность символов, которая не является изменяемым, поэтому вы можете выполнять только арифметические операции над указателями и разыменования указателя для значения.

char *cp = "overflow"; 

std::cout << *++cp std::endl; 
Смежные вопросы