Reputation: 145
I expect to see p and &atbl[1] print the same value (location of element 1) but it differs
struct a {
unsigned int el[4];
};
struct a atbl[3] = {
{0x12131415, 0x01030507, 0x01030507, 0x16171819},
{0xa2a3a4a5, 0x02020202, 0x02020202, 0xa6a7a8a9},
{0xb2c3d4e5, 0x02020202, 0x02020202, 0x0badcafe},
};
struct a * p;
// read address of element 1 in atbl
p = (atbl + (1 * sizeof(struct a)));
printf("%08x %08x %08x %08x %08x\n", p, atbl, &atbl[0], &atbl[1], &atbl[2]);
But I get the following results:
p - dae83240
atbl - dae83140
&atbl[0] - dae83140
&atbl[1]- dae83150
&atbl[2] - dae83160
Any hint ?
Upvotes: 1
Views: 97
Reputation: 105992
Instead of
p = (atbl + (1 * sizeof(struct a)));
you need
p = (atbl + 1 );
If the starting address of the struct atbl
is 1000
(let's say) then adding 1
to it increment it by 16
units and p
points to 1016
(assuming 4
bytes for unsigned int
). It will not increment p
by 1
unit (1001
)
Also, you are using a wrong specifier to print address. This will invoke undefined behavior.
If a conversion specification is invalid, the behavior is undefined.282) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
Use %p
specifier to print address. Your printf
statement should be like:
printf("%8p %8p %8p %8p %8p\n", (void *)p, (void *)atbl, (void *)&atbl[0], (void *)&atbl[1], (void *)&atbl[2]);
Suggested reading: Pointer Arithmetic.
Upvotes: 1
Reputation: 263177
Pointer arithmetic automatically accounts for the size of the pointed-to object; you don't need to multiply by sizeof(struct a)
.
atbl
, after the implicit array-to-pointer conversion, is a pointer of type struct a*
. atbl + 2
points 2 struct a
elements past the address that atbl
points to.
Also, don't use %x
to print pointer values; instead, cast the pointer value to void*
and use %p
.
Upvotes: 3
Reputation: 182743
// read address of element 1 in atbl
p = (atbl + (2 * sizeof(struct a)));
This should be:
p = atbl + 1;
Adding one to something that already points to the first entry will make it point to the second entry. So adding two would make it point to the third entry. You want it to point to the second entry, so you need to add one.
Also, you don't multiply by the size because the pointer already knows the size of the things it points to. Adding one already makes it point to the next object.
Upvotes: 4