Por que não consigo gravar em uma string literal enquanto eu * posso * gravar em um object de string?

Se eu definir algo como abaixo,

char *s1 = "Hello"; 

porque eu não posso fazer algo como abaixo,

 *s1 = 'w'; // gives segmentation fault ...why??? 

E se eu fizer algo como abaixo,

 string s1 = "hello"; 

Posso fazer algo como abaixo?

 *s1 = 'w'; 

Porque "Hello" cria um const char []. Isso decai para um const char* não um char* . Em C ++, literais de string são somente leitura. Você criou um ponteiro para tal literal e está tentando escrever para ele.

Mas quando você faz

 string s1 = "hello"; 

Você copia o const char * “hello” em s1 . A diferença está no primeiro exemplo s1 aponta para somente leitura “hello” e no segundo exemplo somente leitura “hello” é copiado em non-const s1 , permitindo que você acesse os elementos na string copiada para fazer o que você deseja com eles.

Se você quiser fazer o mesmo com um char *, você precisa alocar espaço para os dados char e copiar oi para ele

 char hello[] = "hello"; // creates a char array big enough to hold "hello" hello[0] = 'w'; // writes to the 0th char in the array 

literais de string são geralmente alocados em um segmento de dados somente leitura.

Porque Hello reside na memory somente leitura. Sua assinatura deve ser realmente

 const char* s1 = "Hello"; 

Se você quiser um buffer mutável, declare s1 como char[] . std::string overloads operator [] , então você pode indexar nele, isto é, s1[index] = 'w' .

Hora de confundir as coisas:

 char s0[] = "Hello"; s0[0] = 'w'; 

Isso é perfeitamente válido! É claro que isso não responde à pergunta original, então vamos lá: literais de string são criados em memory somente leitura. Ou seja, o tipo deles é char const[n] onde n é o tamanho da string (incluindo o caractere nulo de terminação, ie n == 6 para a string literal "Hello" . Mas por que, oh, por que esse tipo pode ser usado? inicializar um char const* ? A resposta é simplesmente retrocompatibilidade, respectivamente compatibilidade com [antigo] código C: no momento em que const entrou na linguagem, muitos locais já inicializaram char* com literais de string. Qualquer compilador decente deve avisar sobre este abuso, no entanto.