Por que char * causa comportamento indefinido enquanto char não faz?

A tentativa de modificar um literal de string causa um comportamento indefinido:

char * p = "wikipedia"; p[0] = 'W'; // undefined behaviour 

Uma maneira de evitar isso é defini-lo como uma matriz em vez de um ponteiro:

 char p[] = "wikipedia"; p[0] = 'W'; // ok 

Por que char* causa comportamento indefinido, enquanto char[] não faz?

Qualquer tentativa de modificar um literal de cadeia C tem um comportamento indefinido . Um compilador pode providenciar que literais de string sejam armazenados em memory somente leitura (protegida pelo sistema operacional, não literalmente ROM, a menos que você esteja em um sistema embarcado). Mas a linguagem não exige isso; Cabe a você, como programador, fazer tudo certo.

Um compilador suficientemente inteligente poderia ter avisado que você deveria ter declarado o ponteiro como:

 const char * p = "wikimedia"; 

embora a declaração sem o const seja legal em C (para não quebrar o código antigo). Mas com ou sem um aviso de compilador, o const é uma boa ideia.

(Em C ++, as regras são diferentes; os literais de string C ++, ao contrário dos literais de string C, são realmente const .)

Quando você inicializa uma matriz com um literal, o próprio literal ainda existe em uma região potencialmente somente leitura da imagem do programa, mas é copiado na matriz local:

 char s[] = "wikimedia"; /* initializes the array with the bytes from the string */ char t[] = { 'w', 'i', ... 'a', 0 }; /* same thing */ 

Note que char u[] = *p não funciona – os arrays só podem ser inicializados a partir de um inicializador de chaves, e os arrays de caracteres adicionais de um literal de string.