5

I'm trying something very simple, well supposed to be simple but it somehow is messing with me...

I am trying to understand the effect of ++ on arrays when treated as pointers and pointers when treated as arrays.

So,

int main()
{
    int a[4] = { 1, 4, 7, 9 };
    *a = 3;
    *(a+1) = 4;
    *++a = 4; //compiler error
}

1: So at *(a+1)=4 we set a[1]=4; //Happy But when *++a = 4;, I'd expect pointer a to be incremented one since ++ is precedent to * and then * kicks in and we make it equal to 4. But this code just does not work... Why is that?

Another problem:

int main()
{

    int* p = (int *)malloc(8);
    *p = 5;
    printf("%d", p[0]);

    *++p = 9; //now this works!
    printf("%d", p[1]); //garbage
    printf("%d", p[0]); //prints 9

}

2: Now *++p = 9; works fine but it's not really behaving like an array. How are two different? This is just incrementing p, and making it equal to 9. If I print p[0], it now prints 9 and I see that though can't access it via p[0] anymore, *(p-1) shows 5 is still there. So indexing a pointer with [0], where exactly does it point to? What has changed?

Thanks a lot all experts!

4
  • 1
    An array is not a pointer. You can't increment it. Also, don't cast the return value of malloc. But these have been discussed hundreds of times already. Why don't you do any research before asking? Commented Oct 13, 2013 at 6:28
  • @H2CO3 you don't have to cast malloc's return in C but you do in C++. Commented Oct 13, 2013 at 6:30
  • 1
    @Adam You don't, because you don't use malloc() in C++ at all. Commented Oct 13, 2013 at 6:31
  • Possible duplicate of What happens if I increment an array variable? Commented Mar 11, 2017 at 1:29

2 Answers 2

9

The array names is not modifiable lvalue so operation ++ is not applied hence ++a that try to modify a is compilation time error (where a is array name).

Note *(a + 1) and *a++ are not same, a + 1 is a valid instruction as it just add 1 but doesn't modify a itself, Whereas ++a (that is equvilent to a = a + 1) try to modify a hence error.

Note 'array names' are not pointer. Pointers are variable but array names are not. Of-course when you assign array name to a pointer then in most expressions array names decays into address of first element. e.g.

int *p = a;

Note p points to first element of array (a[0]).

Read some exceptions where array name not decaying into a pointer to first element?

An expression a[i] is equivalent to *(a + i), where a can be either a pointer or an array name. Hence in your second example p[i] is valid expression.

Additionally, *++p is valid because because p is a pointer (a variable) in second code example.

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

4 Comments

This is also the error message compiler is giving. But I'm asking isn't the array name also a pointer, pointing to the first element of an array?
Thanks, can you also please answer the 2nd question? When we dereference a pointer b, to an array a by [0], it prints b[0] as a[1]. So isn't pointer really behaving like an array?
@shadowyman It's more like the array is behaving like a pointer. [] is a pointer operation, it's defined on pointers not on arrays.
Simplified version: Arrays are basically constant, so in using the de/increment operators you're really trying to modify something that cannot be modified. To achieve the desired effect, make a pointer point to the array and increment that.
1
int a[4] = { 1, 4, 7, 9 };
int *pa=a;

There is one difference between an array name and a pointer that must be kept in mind. A pointer is a variable, sopa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa and a++ are illegal


int* p = (int *)malloc(8);

Don't cast result of malloc()

Use index with pointer

p[1]=9; // p[1]==*(p+1)

9 Comments

If we're at it: 1. in standardese parlance, there are no "variables", just objects. So then a pointer isn't a variable either. 2. But if we use the common terminology, then an array is just like any pther normal variable. It's just not assignable.
@H2CO3: your first remark is incorrect. In standardese parlance, "a variable is introduced by the declaration of an object. The variable's name denotes the object." [basic]. That is to say, a variable is any named object introduced by a declaration. You're still right that it's incorrect to say generally that "a pointer is a variable", since for example static_cast<void*>(NULL) is an expression whose value is a pointer that is not a variable (because it isn't named and wasn't introduced by a declaration, and for that matter isn't an object since it doesn't have an address).
However, an array name is (the name of) a variable, even though it cannot vary.
@SteveJessop Right, I retract... I think I have confused the C and the C++ standards. I'll check it.
@H2CO3: ah, if it is different in C then maybe I'm the one who's looking at the wrong one. As I re-read it, nothing in the question requires C++.
|

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.