2016-05-16 4 views
-1

Je ne comprends pas pourquoi le dernier extrait de code imprime 2000 et pas 4000. Une erreur débutant je suppose. Savez-vous? En utilisant DevC++.Dereferencing double pointeur

int val1 = 1000; 
int val2 = 2000; 
int val3[2] = {3000, 4000}; 


int **b[3]; 


*(b+0)= &val1; 
*(b+1) = &val2; 
*(b+2) = &val3; 

//Prints 1000 
//Prints what the first element of b is pointing at 
printf("%d\n",b[0][0]); 
printf("%d\n",**(b+0)); 

//Prints 2000 
printf("%d\n", b[1][0]); 
printf("%d\n",**(b+1)); 

//Prints 3000 
printf("%d\n", b[2][0]); 
printf("%d\n", **(b+2) ); 

//Should print 4000 i think, but prints 2000, why? 
printf("%d\n", b[2][1]); 
printf("%d\n", *(*(b+2)+1) ); 

EDIT: Ce que je voulais était ** b pour être un pointeur sur un tableau ou des pointeurs, mais je suppose que ce qui est arrivé est que je fait ** b un tableau de pointeurs-à-pointeurs au lieu.

Ci-dessous les réponses sont grandes solutions pour que le code fonctionne d'une manière, et voici une solution pour savoir comment faire le travail de code comme je l'ai prévu à l'origine:

Pointer to Array of Pointers

+3

Activer tous les avertissements dans votre compilateur, puis compiler votre code. N'ignorez pas les avertissements. – dreamlax

+1

Le compilateur et le débogueur sont vos amis. Activez tous les avertissements ... (-: – user3078414

+0

Activez les avertissements de votre compilateur et la conformité aux normes pédantes.) Ne demandez pas aux humains des conseils qu'une machine peut vous donner gratuitement –

Répondre

2

Ce programme devrait produire plusieurs avertissements du compilateur. Les corriger va beaucoup plus loin dans la résolution du problème et l'élimination des malentendus. Le type de b est un tableau de pointeur vers pointeur vers int. Voilà pourquoi les deux missions ci-dessous ne sont pas valides:

*(b+0)= &val1; 
*(b+1) = &val2; 

Vous affectez des pointeurs vers int à pointeur à pointer-to-int, ce qui est incorrect.

Le problème est masqué par l'impression d'un pointeur comme si elle était un int:

printf("%d\n", b[0][0]); 

le type de b[0][0] est un pointeur-to-int, mais vous passez à %d, qui l'interprète comme un int. Cependant, la valeur réelle de b[0][0] est int, vous voyez donc la valeur attendue.

Fixation du problème est simple: le changement

int **b[3]; 
... 
*(b+2) = &val3; 

à

int *b[3]; 
... 
*(b+2) = val3; 

Demo.

+0

Merci La raison pour laquelle j'ai écrit le code comme je l'ai fait était parce que je voulais aussi signez le pointeur que b indique avec un pointeur. Je pensais que b pointerait vers un tableau avec 3 pointeurs, mais je suppose que j'ai plutôt créé un tableau avec 3 pointeurs vers des pointeurs. Il devrait y avoir une solution facile à cela, je suppose. – Martin

+0

Oui, c'était ici! :) http://stackoverflow.com/questions/6130712/pointer-to-array-of-pointers – Martin

0

Du point de vue strict de frappe, les lignes:

*(b+0)= &val1; 
*(b+1) = &val2; 
*(b+2) = &val3; 

ont tort.

le type de *(b+0) est identique au type de b[0], qui est int**.
le type de &val1 est int*.

La même incompatibilité de type existe avec *(b+1).

le type de &val3 est int (*)[2].

*(b+2)+1 pointe vers la mémoire qui est différente de l'adresse de val3[1] depuis le pointeur arithmétique est effectué sur un pointeur vers une int*, et non un pointeur vers un int.

Dans les lignes

printf("%d\n",b[0][0]); 
printf("%d\n",**(b+0)); 

Vous passez un int* à la fonction alors que le spécificateur de format attend un int. Le même problème existe avec les instructions printf restantes.

Si vous utilisez gcc, utilisez l'indicateur de compilation -Wall pour détecter ce type de problème.

Vous pouvez résoudre votre problème en utilisant

int *b[3];