Asam Padeh
Asam Padeh

Reputation: 145

Confuse array element address

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

Answers (3)

haccks
haccks

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.

C11: 7.21.6 Formatted input/output functions:

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

Keith Thompson
Keith Thompson

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

David Schwartz
David Schwartz

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

Related Questions