I have the following code, but I can't understand how the result of d is finally -4.
I know it has something to do with pointer arithmetic , but I can't see it clearly.
double dades[5];
double* pDouble = 0;
int* pInt1 = 0;
int* pInt2 = 0;
pDouble = &dades[2];
pInt1 = (int*)(&dades[4]);
pDouble--;
pInt1--;
pInt2= (int*)(pDouble);
pInt2++;
int d = pInt2-pInt1;
The end result, is it one ptrdiff_t
of those?
Could someone explain to me step by step what happens in each line. Thank you
Your question has to do with pointer arithmetic in C/C++.
In such languages, incrementing/decrementing a pointer is not done on a byte -by- byte basis , but depends on the size of the type it points to .
With a small example, we see it better:
When executing the above code, do
a
yb
point to the same absolute address ? Well... it's going to be no .The absolute address would look like this:
Because ? Because, as I said before, the step is not in bytes . The minimum unit is
sizeof( TIPO )
.Since it
a
is(char *)
, the size of achar
, which is 1, is added to it.Since it
b
is(int *)
, it is added to the size of aint
, which, on 32-bit machines, is 4.This is used, although we do not know it , in many situations. For example:
How is it that c points exactly where it is supposed to point ? Because the compiler, internally, does something like this:
The size of the type is clearly indicated when declaring the pointer, and marks it for its lifetime .
I take this opportunity to present to society a curious ally for little things with pointers :
ptrdiff_t
.The type
ptrdiff_t
is platform dependent ; and has several features.ptrdiff_t
.ptrdiff_t
indicates the number of units of distance between 2 pointers , taking into account the type .ptrdiff_t
to bytes , multiply it by the size of the type .Point 2 implies that you cannot add or subtract 2 pointers of different types .
For those who know some C++, it is similar in functionality to
difference_type
STL containers. In fact, forstd::vector< >
, it is normal for it to be:We're getting the hang of this now. If it is not so difficult, man!
Now yes. Armed with our new knowledge, we dare to get our hands on the original problem of the question. We place next to each operation the relative address to
dades
which each pointer points at a given moment:Arriving here,
But... let's remember that the distance depends on the size of the type . If I remember correctly, we agree that
sizeof( int ) == 4
:Take it now!
To do this problem you must understand one thing: the type
int
in c and c++ generally has 4 bytes and the typedouble
8 bytes. Taking into account the above when you add 1 to a pointer type int it will point 4 bytes forward and when you add 1 to a pointer typedouble
it will advance 8 bytes forward. The above is analogous for subtraction.Now look at the sequence below:
Now since it
pInt2
points to the last 4 bytes of the blockdades[1]
and itpInt1
points to the last 4 bytes of the blockdades[3]
, the result is -4.Since: pInt1 is 4 times up if you count in 4-byte blocks: top of
dades[1]=4 bytes
,dades[2]=2*4 bytes
, and bottom ofdades[3]=4 bytes
.