Comportement étrange lors de l’impression de pointeurs

J’ai le code suivant:

#include  typedef struct { int* arg1; int arg2; } data; int main(int argc, char** argv) { data d; printf("arg1: %p | arg2: %d\n", d.arg1, d.arg2); } 

La sortie finit par être que d.arg1 n’est pas NULL et d.arg2 est 0. Par exemple:

 arg1: 0x7fff84b3d660 | arg2: 0 

Lorsque j’ajoute un pointeur à main, rien ne change. Cependant, quand j’imprime ce pointeur:

 #include  typedef struct { int* arg1; int arg2; } data; int main(int argc, char** argv) { data d; int* test; printf("arg1: %p | arg2: %d | test: %p\n", d.arg1, d.arg2, test); } 

la sortie se traduit toujours par:

 arg1: (nil) | arg2: 4195264 | test: (nil) 

Pourquoi est-ce que je vis ce comportement? Je ne comprends pas comment imprimer une autre valeur de pointeur change la valeur d’un pointeur différent en NULL. Notez que le compilateur que j’utilise est GCC 4.8.2.

Vous rencontrez ce problème parce que votre programme appelle un comportement indéfini . d est initialisé dans votre programme et par conséquent sa valeur est indéterminée , ce qui appelle un comportement indéfini.

C11 6.7.9 Initialisation:

Si un object ayant une durée de stockage automatique n’est pas initialisé explicitement, sa valeur est indéterminée.

Citant cette réponse :

Une valeur indéterminée encore plus indéterminée que non spécifiée. C’est soit une valeur non spécifiée, soit une représentation d’interruption. Une représentation de piège correspond à une valeur magique qui, si vous essayez de l’assigner à quelque chose, entraîne un comportement indéfini. Cela ne devrait pas être une valeur réelle; La meilleure façon de penser à cela est probablement “si C avait des exceptions, une représentation de piège serait une exception”. Par exemple, si vous déclarez int i; dans un bloc, sans initialisation, la valeur initiale de la variable i est indéterminée, ce qui signifie que si vous essayez d’atsortingbuer cela à autre chose avant de l’initialiser, le comportement n’est pas défini et le compilateur a le droit d’essayer lesdites démons. tour de nez. Bien sûr, dans la plupart des cas, le compilateur fera quelque chose de moins dramatique / amusant, comme l’initialiser à 0 ou à une autre valeur valide aléatoire, mais quoi qu’il en soit, vous n’avez pas le droit de vous opposer.

Vous devez initialiser d pour obtenir des résultats déterministes:

 data d = {0, 42}; 

ou:

 data d; d.arg1 = 0; d.arg2 = 42; 

Sans initialisation, l’utilisation des valeurs entraîne un comportement indéfini .

Vous accédez à des valeurs non initialisées. Cela provoque un comportement indéfini (ce qui signifie que tout peut arriver, y compris le blocage du programme).

Pour corriger, initialisez les valeurs avant de les utiliser, par exemple:

  data d = { 0 }; 

d n’est pas initialisé, il peut donc contenir n’importe quoi.