Martin
Martin

Reputation: 161

Dereferencing double pointer

I don't get why the last snippet of code prints 2000 and not 4000. Some beginner error I guess. Do you know? Using DevC++.

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: What I wanted was **b to be a pointer to an array or pointers, but I guess what happened is that I made **b an array of pointers-to-pointers instead.

Below in the answers are great solutions for the code to work in one way, and here is a solution for how to make the code work as I originally intended:

Pointer to Array of Pointers

Upvotes: 0

Views: 3178

Answers (2)

R Sahu
R Sahu

Reputation: 206567

From a strict typing perspective, the lines:

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

are wrong.

type of *(b+0) is the same as the type of b[0], which is int**.
type of &val1 is int*.

Same type mismatch exists with *(b+1).

type of &val3 is int (*)[2].

*(b+2)+1 points to memory that is different from the address of val3[1] since the pointer arithmetic is being done on a pointer to a int*, not a pointer to an int.

In the lines

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

You are passing an int* to the function while the format specifier expects an int. Same problem exists with the remaining printf statements.

If you are using gcc, use the compiler flag -Wall to detect these kinds of problems.

You can fix your problem by using

int *b[3]; 

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

This program should produce multiple compiler warnings. Fixing them goes long way toward fixing the problem, and clearing out any misunderstandings.

The type of b is an array of pointer-to-pointer-to-int. That's why the two assignment below are invalid:

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

You assign pointers to int to pointer-to-pointer-to-int, which is incorrect.

The problem is masked by printing a pointer as if it were an int:

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

b[0][0]'s type is a pointer-to-int, but you are passing it to %d, which interprets it as an int. However, the real value of b[0][0] is an int, so you see the expected value.

Fixing the problem is simple: change

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

to

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

Demo.

Upvotes: 2

Related Questions