Click here to Skip to main content
15,888,315 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Guys why is it taking 6 bytes of space between two pointers in my 2d array?

Objective-C
#include<stdio.h>

int main()
{
    int a[2][3]={{0,1,2},{3,4,5}};

    int (*ptr)[3]=a;
    //ptr= a;
    printf("%p\n%p\n%p\n",ptr,((ptr+0)+1),((ptr+0)+2));
        printf("%d\n%d\n%d\n",*(*(ptr)+0),*(*(ptr+0)+1),*(*(ptr+0)+2));
    return 0;

}

output:
0xbfb2ab98
0xbfb2aba4
0xbfb2abb0
0
1
2
Posted
Updated 28-Jul-14 8:05am
v3

It isn't.
Those are Hexadecimal numbers so:
0xbfb2aba4 - 0xbfb2ab98 != 6
Instead:
0xbfb2aba4 - 0xbfb2ab98 == 12 (decimal) or 0x0c (Hexadecimal)
 
Share this answer
 
v2
Comments
Jeevan83 28-Jul-14 14:49pm    
Ok if it's 10 then why 10? A pointer should take 4 right? Please tell me more clearly! Then i tried above code with %u in place of %p, then i got this :
3213576616
3213576628
3213576640
Here there is 12 difference, why is that? I mean they are consecutive values and integers, so there should be 4 bytes difference right?
OriginalGriff 28-Jul-14 14:58pm    
You're right - my mental arithmetic was faulty: it's 12, not ten.
Why?
Who says they are consecutive integers?
Is that what your definition of ptr says?
Because it doesn't look like it to me...
OriginalGriff 28-Jul-14 15:04pm    
Stop and think about your code:
int (*ptr)[3]=a;
is not the same as
int *ptr = &a[0][0];

It declares ptr to be a pointer to an array of three integers: so when you advance ptr by one, you move it on by the space required for three integers: 4 bytes each, times 3 == 12.

And if you think about it, that makes sense.
When you do this:
char* pc = ...
pc = pc + 1;
You want it to advance by one character - a single byte
But when you do this:
int* pi = ...
pi = pi + 1;
You want it to advance by the size of an integer - 4 bytes in this case. Anything else would cause huge problems!
So when you declare a pointer, the increment is the size of the type it is declared to point to.
int (*ptr)[3]
Is a pointer to an array of three integers.
Jeevan83 28-Jul-14 15:09pm    
Bro you are the best actually I know that but because of lot of confusion I missed that. Thanks a lot and sorry for wasting your time!
OriginalGriff 28-Jul-14 15:10pm    
You're welcome!
Your ptr defines a pointer to an array of three ints (i.e. one row of your matrix).
If you do pointer arithmetic, the compiler does for you the size calculations. If you add 1 to the current row address, you get the address of the next row.
You seem to work on a machine where int has a size of 4 bytes, so the row has size of 3*4 = 12 bytes. This leads to a next row at 12 bytes apart of the former row.

You pointer arithmetic is very much obfuscating. Why the heck do you do this? Work with indices instead! And if you need the address of some element, use the address-of operator, e.g. &(a[1][2]);, etc.
Cheers
Andi
 
Share this answer
 
Comments
Jeevan83 29-Jul-14 8:56am    
Thanks! Ya you are right I could use indices, but trying for something new I pushed myselves into this :D
Andreas Gieriet 29-Jul-14 11:03am    
Ok, good point!

Pointer arithmetic is an item that needs carful examination when used.
The syntax (how to write such things) and the semantics (the meaning of the written code) is not so obvious.

To exercice a bit, write down the memory layout of your matrix. e.g. for the purpose of the exercise, let's assume the address of the first byte of array a at address 0xC000

Address Value
0xC000 0
0xC004 1
0xC008 2
0xC00C 3
0xC010 4
0xC014 5

You see that the layout is such that all values are "row-wise" stored in sequence. I.e. from innermost to outermost: for a matrix, row by row. For a 3d array (e.g. t[x][y][z]), x planes of y columns of z rows, etc.

An address is just a memory location. The language interpretes according to your given type of a variable at that memory location, what to do with the memory at that location and how to do pointer arithmetic.

Cheers
Andi
Jeevan83 31-Jul-14 7:27am    
Thanks man! :)
Answers 1 and 2 are both correct. But nevertheless, your last comment shows that there is still some kind of surprise in your code. If ptr points to int[3] arrays, why does the second printf show the consecutive values of 0, 1, 2 then?

The answer is partly contained in your comment:
"Then ((ptr+0)+0) is ptr[0][0], ((ptr+0)+1) is ptr[0][1] and ((ptr+0)+2) is ptr[0][2] right?"

No, that is not correct. "((ptr+0)+1)" is the same as "ptr+1" and that again is the same as &ptr[1] and that again is the same as &ptr[1][0]. The parentheses work just as always in arithmetic expressions. That is the reason you see an increment of 12 in the first printf.

In your second printf, you wrote expressions like *(*(ptr+0)+1). Notice that the dereference operator (*) binds stronger than the addition, so that means:
C++
*(   (*(ptr+0))  + 1  )

which again is
C++
*( (*ptr) + 1 )

The *ptr delivers a int[3]. You can't add 1 to an integer array, so the compiler converts it to an int*. Adding 1 gets you the next consecutive int cell. And that is why you are seeing 0, 1, 2.
Or, in other words, (*(ptr+0)+1) does correspond to &ptr[0][1], while ((ptr+0)+1) does not.

Got it now?
 
Share this answer
 
Comments
Jeevan83 29-Jul-14 8:58am    
Yes haha 100% clear! Thanks. But i deleted my comment how come you still see that? grr... Thanks! This shows that I require some more time to spend on pointers and arrays. You guys are great man all 3 of you, I never know how you guys master this concept! (sigh)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900