2013-06-17 7 views
0

Dans le programme suivant, p est déclaré comme pointeur (ce qui est constant, mais pas la chaîne BUT). Mais le programme ne fonctionne toujours pas et s'arrête brusquement en disant "untitled2.exe a cessé de fonctionner" .C: Utilisation du pointeur char * const

#include<stdio.h> 
#include<stdlib.h> 

int main(){ 
    char * const p = "hello"; 
    *p = 'm'; 
    return 0; 
} 

Pourquoi ce comportement inattendu?

+0

Cela ne semble même pas devoir être compilé. La première ligne de 'main' manque un point-virgule, pour un. – Gian

+2

"bonjour" est un littéral et stocké en memmory statique, il ne peut pas être modifié. – BillHoo

+1

http://stackoverflow.com/questions/890535/what-is-the-difference-between-char-const-and-const-char/890560#890560 Rappelez-vous que, en règle générale, chaque fois que vous êtes en utilisant 'const' vous déclenchez des actions internes effectuées par le compilateur. – user2485710

Répondre

5

Bien que p lui-même est un pointeur vers un objet non const, il pointe vers un littéral de chaîne. Un littéral de chaîne est un objet qui, même s'il n'est pas const - qualifié en ce qui concerne son type, est immuable.

En d'autres termes, p pointe vers un objet qui n'est pas const, mais se comporte comme si elle était.

En savoir plus sur ANSI/ISO 9899: 1990 (C90), section 6.1.4.

5

Vous obtenez une erreur Windows parce que vous accédez de manière invalide à la mémoire. Sur d'autres systèmes, vous pouvez obtenir une erreur SEGFAULT ou SEGV ou une erreur de bus.

*p = 'm'; 

tente de changer la première lettre de la chaîne constante « bonjour » de « h » à « m »;

+0

DEP concerne le marquage de la mémoire non exécutable. Cela n'a rien à voir avec le marquage de la mémoire constante ou non. (-1) –

+0

Comme la réponse a été corrigée, suppression de la version supprimée. –

2
char * const p = "hello"; 

définit un pointeur constant p et il initialise avec l'adresse de mémoire d'une chaîne constante "hello" qui est en soi de type const char *. Par cette affectation, vous supprimez un qualificatif const. C'est un C valide, mais conduira à un comportement indéfini si vous ne savez pas ce que vous faites.

esprit que const char * vous interdit de modifier le contenu de la mémoire pointée, mais ne l'empêche pas de changer l'adresse en char * const permet vous de modifier le contenu, mais fixe l'adresse. Il existe également une version combo const char * const.

Bien que ce code C soit valide, en fonction de l'emplacement de votre système d'exploitation et des restrictions sur "hello", il peut ou non se retrouver dans la mémoire inscriptible. Ceci est laissé indéfini. En règle générale, les chaînes de caractères constantes font partie du texte du programme exécutable et sont en lecture seule. Ainsi, en essayant d'écrire à *p, vous obtenez une erreur d'autorisation de mémoire SIGSEGV.

La manière correcte est de copier le contenu de la chaîne à la pile et y travailler:

char p[] = "hello"; 

Maintenant, vous pouvez modifier *p car il est situé sur la pile qui est en lecture/écriture. Si vous en avez besoin globalement, placez-le dans la portée globale.