12

I know this has been hashed over a number of time, but I have come across a case today that shook my understanding of the pointer math/ array index.

As I have allways understood it, &mybuff[10] and (&mybuff+10) are equivilent ways of referancing the same memory.

However I spent the morning fighting a case where:

memcpy(&mybuff+10,&in,8); 

overflowed the buffer, when compiled with optimization on and worked just fine when compiled for debugging.

While athe same time,

memcpy(&mybuff[10],&in,8); 

worked just fine in both cases.

Many thanks for any ideas or pointers.

4
  • 11
    tee hee at the pun asking for "pointers" Commented Aug 18, 2011 at 20:58
  • 9
    Some pointers. Commented Aug 18, 2011 at 21:06
  • 1
    &mybuff[10] evaluates to &(*(mybuff+10)), which is different from &mybuff + 10. Remember that postfix operators like [] have higher precedence than unary operators like &. Commented Aug 18, 2011 at 21:06
  • possible duplicate of C: How come an array's address is equal to its value? Commented Aug 18, 2011 at 21:51

7 Answers 7

8

I'll invent a declaration for mybuff for the sake of the example:

char mybuff[123];

Now, &mybuff+10 does pointer arithmic on &mybuff, which has the type "pointer to array of 123 chars". This is different from plain mybuff which (after pointer decay) has type "pointer to char". The bit value of these two expressions is the same, but because they are pointers to things of different sizes, they behave differently under pointer arithmetic.

&mybuff+10 means that you want to step past ten of the 123-char arrays in the type (which is meaningless given the declaration and may segfault), whereas mybuff+10 just says that you want to step past ten individual chars.

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

Comments

7

see http://cplusplus.com/doc/tutorial/operators/ for priority order of operators
&mybuff+10 like (&mybuff)+10
&mybuff[10] like &(mybuff[10])

Edit
also some pointers http://cplusplus.com/doc/tutorial/pointers/

Comments

5

&mybuff[10] is equivalent to &mybuff[0] + 10 which is equivalent to mybuff + 10

Array indexing is defined in terms of pointer arithmetic. p[i] means *(p+i) (I'm ignoring the need for extra parentheses in case p or i is a more complex expression), where p is a pointer value and i is an integer value.

Trivia: Since addition, even pointer+integer addition, is commutative, p[i] can also be written as i[p]. Yes, 4["Hello"] == 'o'. For the sake of anyone who reads your code in the future, please do not make use of this knowledge.

An excellent reference on the relationship between arrays and pointer in C (and C++, where the rules are nearly identical) is section 6 of the comp.lang.c FAQ. (I could have linked directly to section 6, but I like to encourage people to browse it; the whole thing is worth reading.)

Comments

2

I think you've got some pointer problems.
If mybuff is a pointer then mybuff + 10 == &(mybuff[10]).
That's not the same as &mybuff + 10 like you've got there.

Comments

2

(&mybuff+10) and &mybuff[10] are not equivalent, but &mybuff[10] and mybuff + 10 are.

4 Comments

Not quite; &mybuff[10] parses as &(mybuff[10]), which is evaluated as &(*(mybuff + 10)).
Which is equivalent to mybuff + 10.
just remove or edit first line of our answer, because it is not clear for beginners
If we want to be completely language-lawyery about it, the correct thing to say would be that whenever &mybuff[10] has a defined behavior, that behavior is the same as mybuff+10. However, if mybuff is a 10-element array, then the implied deference in &mybuff[10] is past the end of the object and arguably triggers undefined behavior (though I think I've seen others argue that it doesn't count as a dereference for that purpose when the *foo is immediately consumed by an address-of operator), whereas mybuff+10 is defined.
1

The correct syntax is mybuff+10 not &mybuff+10 which says move to position 10 in your array and copy 8 bytes (per your memcpy statement). It is still unknown whether you can actually hold an additional 8 bytes though.

3 Comments

@user12861: Go here - learncpp.com/cpp-tutorial/…
I'm saying this answer isn't clear. Personally, I know at least this much C++.
@user12861: I'm sure the OP understands what the hell I am talking about. It is very clear.
1

The reason it worked in debug mode is because in debug mode, the memory is initialized for you and allocations are also larger than the actual size. http://msdn.microsoft.com/en-us/library/bebs9zyz(v=vs.80).aspx

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.