4

I have this multi-dimensional array:

char marr[][3] = {{"abc"},{"def"}};

Now if we encounter the expression *marr by definition (ISO/IEC 9899:1999) it says (and I quote)

If the operand has type 'pointer to type', the result has type 'type'

and we have in that expression that marr decays to a pointer to his first element which in this case is a pointer to an array so we get back 'type' array of size 3 when we we have the expression *marr. So my question is why when we do (*marr) + 1 we add 1 byte only to the address instead of 3 which is the size of the array.

Excuse my ignorance I am not a very bright person I get stuck sometimes on trivial things like this.

Thank you for your time.

1
  • size of "abc" is 4, char a[4] = "abc";// { 'a','b','c','\0' } Commented Dec 5, 2011 at 22:35

2 Answers 2

3

The reason why incrementing (*marr) moves forward 1 byte is because *marr refers to a char[3], {"abc"}. If you don't already know:

*marr == marr[0] == &marr[0][0]
(*marr) + 1 == &marr[0][1]

If you had just char single_array[3] = {"abc"};, how far would you expect single_array + 1 to move forward in memory? 1 byte right, not 3, since the type of this array is char and sizeof(char) is 1.

If you did *(marr + 1), then you would be referring to marr[1], which you can then expect to be 3 bytes away. marr + 1 is of type char[][3], the increment size is sizeof(char[3]).

The key difference about the two examples above is that:

  • The first is dereferenced to a char[3], and then incremented, therefore the increment size is sizeof(char).
  • The second is incrementing a char[][3], therefore the increment size is sizeof(char[3]), and then dereferencing.
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you sir your answer is also very much appreciated and helpful. You guys are great.
1

It adds one because the type is char (1 byte). Just like:

char *p = 0x00;
++p; /* is now 0x01 */

When you dereference a char [][] it will be used as char * in an expression.

To add 3, you need to do the arithmetic first and then dereference:

*(marr+1)

You were doing:

(*marr)+1

which dereferences first.

4 Comments

Thank you for your quick answer I understand everything you've said here except when you say "When you dereference a char [][] it will be used as char * in an expression" Why is that ? doesn't the name of the array decay to a pointer to its first element which in this case is a pointer to an array of size 3 so the type is char array of size 3 ?
@wel yep, a char [][] wil decay into char (*)[], right? (pointer to array, just like you said) so when you dereference it, you'll have a char array. But this one, when used in an expression, decays into a pointer to its first element (again), so you end up with char *. And incrementing a pointer to a char adds 1 . If instead you do *(marr+1), first you have marr decaying into a pointer to array of size 3, and incrementing it increments it's type size (which is array of size 3 of char) so you get a +3 increment. Then you dereference this one. It's kind of hard, yes…
Thanks my friend I've got it now. I sort of figure this at first but was very unsure thanks for your patience and time. Your answer is incredibly helpful.
Glad to help @wel . These things can be really confusing! Best wishes and welcome to StackOverflow!

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.