2015-06-19 15 views
5

I puntatori di caratteri in C mi confondono.Confusione sui puntatori di caratteri in C

Supponiamo di avere un puntatore char, che punta al primo carattere della stringa costante.

char *a="ABCD"; 

allora non possiamo cambiare il valore di quel personaggio utilizzando il puntatore di una, come in seguito i risultati economico in un errore di segmentazione.

*a='X'; 

Supponiamo ora di avere un puntatore char, che punta a un personaggio costante.

const char B='X';  
char *ptr=&B; 

Poi ci sono autorizzati a modificare il valore di quel personaggio utilizzando l'istruzione

*ptr='Z'; 

La mia domanda è che questo è un caso di comportamento non definito dimostrando C non è robusto? O c'è una logica più profonda coinvolta?

+0

@EugeniuRosca intendi 'char const * a =" ABCD "'. Non hanno la stessa semantica. – Quentin

+0

const indica che la memoria è in sola lettura. Periodo. Non sei autorizzato a cambiarlo facendo riferimento a un altro puntatore - questo dovrebbe generare un avviso del compilatore. –

+1

Dai un'occhiata a http://stackoverflow.com/questions/2589949/c-string-literals-where-do-theygo – xp500

risposta

5

Il motivo per il puntatore si comporta in modo diverso è che il programma C ha diversi segmenti di memoria, alcuni dei quali sono protetti.

Quindi non è possibile modificare il valore di quel carattere utilizzando il puntatore a, poiché l'istruzione seguente genera un errore di segmentazione.

A differenza di altre costanti, le costanti di stringa vengono posizionate in un segmento protetto. Qualsiasi tentativo di modificare questo segmento comporta un comportamento indefinito (ad esempio, il tuo programma potrebbe essere segfault).

Poiché il puntatore punta a una costante di stringa, il valore a cui punta non può essere modificato.Se si forza una copia della costante in memoria modificabili utilizzando una matrice, la stessa modifica sarebbe stato permesso:

char a[]="ABCD"; 
*a='X'; 

Poi c'è permesso di modificare il valore di quel personaggio [single] utilizzando l'istruzione

Questo perché la costante di carattere viene sempre copiata in una memoria modificabile.

5

In C, la modifica del letterale stringa non è consentita.

char *a="ABCD"; 

è equivalente a

char const *a="ABCD"; 

*a='X'; si modifica la stringa letterale ABCD. Mentre nel secondo caso, ptr punta a un carattere che non dovrebbe essere modificato e *ptr='Z'; modificherà il contenuto della posizione che contiene X che non è valido.

Si noti che la modifica di un oggetto qualificato const è una violazione del vincolo.

+1

La modifica di '* ptr' non è valida minimamente. – Quentin

+0

@Quentin; Oops! Concordato. Mancato quello specificatore 'const'. – haccks

7

Diciamo che C ti permette di spararti facilmente nel piede. La modifica di B è comunque un comportamento non definito, proprio come la modifica di *a, perché B è stato dichiarato const.

per aiutare con questo, accendendo gli avvertimenti (che si dovrebbe sempre fare se non in circostanze molto specifiche) porta in primo piano il seguente su GCC:

warning: initialization discards 'const' qualifier from pointer 
     target type [-Wdiscarded-qualifiers]