1

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 ?

3
  • atbl is a pointer, so you are using pointer arithmetic. Commented Jan 8, 2014 at 19:02
  • For starters, the statement p = (atbl + (2 * sizeof(struct a))); gets me an out of bounds pointer arithmetic error: 465 bytes (30 elements past end of array. Commented Jan 8, 2014 at 19:04
  • I am sorry I edited the p equation above, from 2 to 1. Commented Jan 8, 2014 at 19:13

3 Answers 3

4
// 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.

Sign up to request clarification or add additional context in comments.

4 Comments

"the pointer already knows the size of the things it points to" Is it because my struct is only four unsigned int ? How about if it is a complex ADT ?
@AsamPadeh If the type is known, its size is known. Basically, you get the same thing you'd get if you did sizeof (*atbl).
interesting, sizeof(*atbl). atbl itself is a pointer to a (i.e &atbl[0]) so sizeof(*atbl) is the size of the pointer? How can a pointer have size ?
@AsamPadeh Yes. sizeof(*atbl) is the size of what atbl points to. If that's a pointer (because atbl is a pointer to a pointer), then it's the size of that pointer.
3

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.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.