0

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

Community
  • 1
  • 1
Martin
  • 151
  • 2
  • 9
  • 3
    Enable all warnings in your compiler, and then compile your code. Don't ignore warnings. – dreamlax May 16 '16 at 13:09
  • 2
    Compiler and debugger are your friends. Turn all warnings on… (-: – user3078414 May 16 '16 at 13:09
  • Enable your compiler warnings and pedantic standard conformance. Don't ask humans for advice that a machine can give you for free. – Kerrek SB May 16 '16 at 13:09
  • Mixing types like you do is bad, and will lead to bad things happening, and it is of course generally unreadable, hard to understand what's happening, and will be unmaintainable by anyone but you *for the moment*. Do you think you will be able to come back to this in a couple of months when you started to forget it, and understand what you were doing? – Some programmer dude May 16 '16 at 13:11
  • 1
    `int **b[3];` --> `int *b[3];`, `*(b+2) = &val3;` --> `*(b+2) = val3;` – BLUEPIXY May 16 '16 at 13:14
  • Possible duplicate, or a post where a valid answer can apply: [SO](http://stackoverflow.com/questions/13974001/two-dimensional-array-implementation-using-double-pointer) – user3078414 May 16 '16 at 13:14

2 Answers2

2

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thank you! The reason why I wrote the code like I did was because I wanted to assign the pointer b is pointing to with a pointer. I thought that b would point to an array with 3 pointers, but I guess I instead created an array with 3 pointers-to-pointers. There should be an easy solution to that I guess. – Martin May 16 '16 at 14:13
  • Yep, here it was! :) http://stackoverflow.com/questions/6130712/pointer-to-array-of-pointers – Martin May 16 '16 at 14:28
0

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]; 
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
R Sahu
  • 204,454
  • 14
  • 159
  • 270