changer la valeur de l’un des pointeurs dans le cas où l’adresse de deux pointeurs est identique

J’ai un problème, j’ai vu que l’adresse de deux pointeurs est la même que celle dont il est question ici (les adresses de deux pointeurs sont identiques ), également répondue par blue moon. Ce qui me conduit à d’autres doutes. Étant donné que les deux pointeurs ont la même adresse, j’ai pensé modifier la valeur de l’un des pointeurs; l’attente de la valeur sera également modifiée dans un autre pointeur (car ils ont la même adresse). Mais sa faute de segmentation donne. Je le montre dans un code ci-dessous.

#include #include int main() { char * p = "abc"; char * p1 = "abc"; printf("%d\n %d\n", (void *)p, (void *)p1); printf("%s\n %s\n", p, p1); *p = 'b'; printf("%d\n %d\n", p, p1); printf("%s\n %s\n", p, p1); } 

C90, 6.1.4

Si le programme tente de modifier un littéral de chaîne de l’une ou l’autre forme, le comportement n’est pas défini.

Dans votre cas, ce comportement indéfini est en votre faveur, de sorte que vous obtenez une erreur distincte. Autre que ce pointeur d’impression utilisant %d n’est pas une bonne pratique, vous devez utiliser %p .

Maintenant, à partir de votre réponse de lien donnée de Blue Moon

vous devez toujours traiter p et p1 comme deux pointeurs différents (même s’ils ont le même contenu) car ils peuvent pointer ou non vers la même adresse. Vous ne devriez pas compter sur les optimisations du compilateur.

Le code

 char * p = "abc"; 

Peut mettre le littéral de chaîne dans la mémoire en lecture seule, donc techniquement, vous ne devriez pas le modifier. Cela pourrait vous donner la faute seg. C’est aussi pourquoi les deux pointeurs peuvent être identiques … le compilateur est assez intelligent pour reconnaître qu’ils utilisent tous les deux le même littéral de chaîne, de sorte qu’ils ne stockent qu’une seule instance du littéral.

Si vous l’avez déclaré comme

 char p[] = "abc" 

Cela créerait alors un tableau lisible / inscriptible de 4 caractères (3 et 1 terminateur nul) sur la stack, que vous pourriez ensuite modifier, cependant …

 char p[] = "abc"; char p1[] = "abc"; 

Vous constaterez que p1 != p car les deux sont créés avec un stockage séparé sur la stack (je suppose qu’ils ne sont pas globaux)

De même, lorsqu’on utilise printf pour imprimer les valeurs de pointeur, il est préférable d’utiliser %p .

 char * p = "abc"; *p = 'b'; 

invoque un comportement indéfini puisque vous essayez de modifier la mémoire en lecture seule. Vous ne pouvez pas modifier la mémoire, où réside ce littéral chaîne constant.

Utilisez ce littéral pour initialiser un tableau à la place:

 char myStr[] = "abc"; char *p = &myStr[0]; char *p2 = &myStr[0]; // <-- p and p2 point to the same address now *p = 'b'; printf("%s\n", p2); // <-- prints bbc 

Les littéraux de chaîne étant stockés dans des segments de mémoire en lecture seule, les tentatives de modification entraînent des erreurs de segmentation. En effet, les données de littéraux de chaîne peuvent être référencées par de nombreux pointeurs et leur modification modifierait les autres chaînes de constantes.