Pointeur sur la chaîne const en C

char *p = "ssortingng"; //creates pointer to constant ssortingng char p[] = "ssortingng"; //just an array with "ssortingng" 

Je ne comprends pas très bien pourquoi, dans le premier exemple, crée-t-il un pointeur sur une chaîne constante? Ne devrait-il pas s’agir simplement d’un pointeur faisant référence à un emplacement en mémoire avec “chaîne”?

Il est malheureusement légal en C (et en C ++ 03, par compatibilité). Mais toute tentative de modification du littéral de chaîne via le pointeur entraînera un comportement indéfini. Donc, mieux vaut toujours assigner le littéral chaîne à un caractère const char*

 const char * cp = "Hello"; //OK char* p = "Hello"; //OK in C and C++03 (unfortunately), Illegal in C++11 cp[0] = 'Y'; //Comstack-time error, good p[0] = 'Y'; //no comstackr error, undefined behavior 

Dans le premier cas, "ssortingng" peut être stocké dans une zone en lecture seule du processus, de sorte que toute tentative de modification de la mémoire pointée par p provoquerait un comportement indéfini.

Dans le second cas, la mémoire réelle est allouée et initialisée sur la stack au moment de l’exécution (ou dans une section appropriée du processus au démarrage du programme si ce n’est pas une variable locale), ce qui permet de modifier la mémoire.

Le premier cas peut être illustré comme ceci:

 +---+ +---+---+---+---+---+---+---+ | | ----> | s | t | r | i | n | g | \0| +---+ +---+---+---+---+---+---+---+ p 

Considérant que le second cas est:

 +---+---+---+---+---+---+---+ | s | t | r | i | n | g | \0| +---+---+---+---+---+---+---+ p 

Les deux déclarations présentent une différence significative, même si vous avez peut-être entendu dire qu’elles sont identiques dans les livres de programmation en C de faible qualité.

Le premier est un pointeur de type char * , tandis que le second est un tableau de type char [] . Les identificateurs de tableau se désintègrent en un pointeur dans certains contextes, mais cela ne les rend pas des pointeurs.

Un pointeur est simplement une adresse et un tableau est “le tout” – dans le premier cas, sizeof(p) donne la taille d’un pointeur (généralement 4 ou 8 fonction de la machine cible), et dans le second cas, elle donne 7 * sizeof(char) , la longueur de la chaîne réelle.

Le premier crée un pointeur et le définit sur l’adresse d’une chaîne constante (probablement dans une région sans protection en écriture sur les pages). Ecrire sur ce pointeur est illégal (et va probablement planter).

Le second crée un tableau et y copie des caractères. Ecrire dans ce tableau écrira à un endroit de votre stack et est parfaitement légal.

Dans le premier cas, “chaîne” peut être stocké dans une zone en lecture seule du processus, de sorte que toute tentative de modification de la mémoire pointée par p provoquerait un comportement indéfini.

Cela peut être prouvé en exécutant la ligne de codes ci-dessus à plusieurs resockets.

 char *p="ssortingng"; 

vous remarquerez que le contenu de p (c’est-à-dire l’adresse de “chaîne”) rest constant.

 char p[] = "ssortingng"; 

car ces mémoires sont allouées à chaque fois que vous exécutez le contenu de p modifications.