2013-01-24 4 views
2

J'ai lu ceci sur wikipediaPourquoi une erreur de segmentation dans le code suivant?

int main(void) 
{ 

    char *s = "hello world"; 
    *s = 'H'; 

} 

Lorsque le programme contenant ce code est compilé, la chaîne « Bonjour tout le monde » est placé dans la section du fichier exécutable du programme marqué en lecture seule; lorsqu'il est chargé, le système d'exploitation le place avec d'autres chaînes et des données constantes dans un segment de mémoire en lecture seule. Lorsqu'elle est exécutée, une variable, s, est définie pour pointer sur l'emplacement de la chaîne, et une tentative est faite pour écrire un caractère H dans la mémoire, provoquant une erreur de segmentation **

Je ne sais pas pourquoi la chaîne est placée en lecture seule segment.please quelqu'un pourrait expliquer cela.

+0

duplication possible de [C: différences entre le pointeur et le tableau] (http://stackoverflow.com/questions/1335786/c-differences-between-pointer-and-array) –

Répondre

3

Les littéraux de chaîne sont stockés dans la mémoire morte, c'est ainsi que cela fonctionne. Votre code utilise un pointeur initialisé pour pointer sur la mémoire où un littéral de chaîne est stocké, et donc vous ne pouvez pas modifier valablement cette mémoire.

Pour obtenir une chaîne en mémoire modifiable, faites ceci:

char s[] = "hello world"; 

alors vous êtes très bien, puisque maintenant vous êtes juste en utilisant la chaîne constante pour initialiser un tableau non constant.

+1

Pour être pédantes, ils n'ont pas tapez 'const char *' ... –

+0

@OliCharlesworth Doh. J'aurais dû savoir que c'était trop simple. Réécrit, et merci. – unwind

+0

@unwind il n'y aurait pas de * question * si les chaînes de caractères étaient 'const char *': le code ne compilerait pas (c'est pourquoi j'ai downvoted - et je supprime le downvote lorsque vous le corrigez). Cela dit, dans toutes les réponses jusqu'à présent, il n'y a aucune tentative d'expliquer le * but * de déplacer des littéraux de chaîne à des sections en lecture seule. (On ne sait pas si la question demande le but ou «c'est comme ça que ça fonctionne» est suffisant). –

2
  • Quand vous faites: char *s = "hello world"; alors s est un pointeur qui pointe vers une mémoire qui se trouve dans la partie de code , de sorte que vous ne pouvez pas modifier.

  • Quand vous faites: char s[] = "Hello World"; alors s est un tableau de caractères qui sont sur la pile, de sorte que vous pouvez changer.

Si vous ne voulez pas la chaîne à changer au cours du programme, il est préférable de le faire: char const *s = ....;. Ensuite, lorsque vous essayez de modifier la chaîne, votre programme ne plantera pas avec le défaut de segmentation, il se produira une erreur de compilation (ce qui est beaucoup mieux).

3

Il y a une grande différence entre:

char * s = "Hello world"; 

et

char s[] = "Hello world"; 

Dans le premier cas, s est un pointeur vers quelque chose que vous ne pouvez pas changer. Il est stocké dans la mémoire en lecture seule (généralement, dans la section de code de votre application). Dans ce dernier cas, vous allouez un tableau dans une mémoire de lecture-écriture (généralement de la mémoire vive) que vous pouvez modifier.

+1

Dans le premier cas, je m'attends également à ce que le compilateur émette un avertissement à propos de l'affectation d'un const à un non-const ou quelque chose. – junix

0

premiers ont une bonne compréhension des pointeurs, je donnerai u une courte démonstration:

Tout d'abord laissez-nous analyser votre code ligne par ligne.Commençons à partir du début

char * s = "Some_string"; Tout d'abord, vous déclarez un pointeur vers une variable char, maintenant * s est une adresse en mémoire, et C vous donnera un coup de pied si vous essayez de changer sa valeur de mémoire, c'est illégal, donc mieux vaut déclarer un personnage array, puis assigne s à son adresse, puis change s.

J'espère que vous l'aurez compris. Pour plus de référence et une compréhension détaillée, se référer KN King: C programmation Une approche moderne

0

Selon la définition du langage, les littéraux chaîne doivent être stockés de telle sorte que leur durée de vie s'étend sur la durée de vie du programme, et qu'ils sont visible sur l'ensemble du programme.

Exactement ce que cela signifie en termes de la chaîne est stockée est jusqu'à la mise en œuvre; la définition de la langue n'impose pas que les littéraux de chaîne soient stockés dans la mémoire morte, et toutes les implémentations ne le font pas. Il dit seulement que tenter de modifier le contenu d'un littéral de chaîne entraîne un comportement indéfini, ce qui signifie que l'implémentation est libre de faire ce qu'elle veut.

Questions connexes