Incrementing pointer not working - c++

I’m trying to increment pointer. I was sure that it is similar to do i+=1 , but I’m getting adress.
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int i = 42;
int *a = &i;
*a++;
cout << *a;
cin.get();
return 0;
}
Can anybody explain why ?

++ has a higher operator precedence than the pointer dereference operator *.
So what *a++ does is to return the value of i (the old value of *a) before incrementing the pointer value.
After that expression has been evaluated, a now points to something other than the address of i, and the behaviour of a subsequent *a is undefined.
If you want to increment i via the pointer, then use (*a)++;

If you want your output to be "43", than you have to change *a++; to (*a)++;.
But other than for testing and learning, code like yours is more of a "C thing" than a "C++ thing". C++ offers another approach to referencing data and operating on it, through what the language calls “references”.
int i=42;
int &a=i; // ‘a’ is a reference to ‘i’
a++;
assert(i==43); // Assertion will not fail
References are especially useful for passing arguments to functions, without the risk of having null or displaced pointers.

What does "I'm getting adress" mean?
Have you checked out order of operations?
http://en.cppreference.com/w/cpp/language/operator_precedence
++-postfix is a higher precedence than *-dereference - hence:
*a++;
is really:
*(a++);
and not:
(*a)++;
... as you probably meant. Which is IMHO why I always recommend erring on the side of too many parentheses rather than too few. Be explicit as to what you mean :)

You have used *a++;
As your increment operator ++ has higher precedence than your pointer *, what actually is happening is that your pointer address is being incremented. So the new *a has no defined value and hence it will give an undefined value
*a++; is the equivalent of a++;
To fix this you can use parentheses (*a)++; or simply us pre increment operator ++*a;

Your code works fine till you reach the line
*a++;
As you know, C++ compiler will break this code of line as
*a = *(a+1);
That is, it will first increment address value of a and then assign the value to *a. But if you do,
*(a)++;
then you will get correct output, that is, 43.
For output- http://ideone.com/QFBjTZ

Related

In C or C++, is there a way to get the address of i++ or ++i ("i" is int type)?

Is there a way to write something like below:
int i = 0;
int *p1 = &(i++);
int *p2 = &(++i);
Before asking "Is there a way", I think we have to ask, "What would it mean?"
In C, we have the concept of "object" versus "value". Basically, an object is a thing that can hold a value. So a variable like
int a;
is clearly an object, because it can hold a value — that is, we can say things like
a = 5;
to store a value into a.
The key distinction between an object and a value is that an object has a location. A value, on the other hand, is something we've computed that's just kind of floating in space, and if we don't find an object to store it in pretty soon, it disappears.
(Side note: You will sometimes come across the terms "lvalue" and "rvalue", which mean the same thing as "object" and "value" as I've been using them here. An lvalue is something that can appear on the left side of an assignment operator, while an rvalue is something that can only appear on the right.)
I've gone through this longish background introduction just so I can make this important point: You can only apply the address-of operator to an object, because only objects have locations. It makes perfect sense to say
int *p = &a;
But it would make no sense to say
int *p2 = &5; /* WRONG */
or
int *p3 = &(1 + 2); /* WRONG */
So it would equally make no sense to write
int *p4 = &(a + 1); /* WRONG */
The variable a is an object, but the thing that you get by fetching a's value and adding 1 to it is clearly just a value. By the time we've computed that value, it doesn't really matter (we might as well have forgotten) that one part of the computation of that value involved fetching a value from the object a.
But then we get you your questions. Suppose you try to write
int *p5 = &(i++); /* questionable */
int *p6 = &(++i);
The ++ operator takes a value and adds 1 to it, and the value i + 1 is clearly just a value, without a location. But, its true, i++ and ++i mean more than just "i + 1" — they compute the value i + 1 and store it back into i. So you can almost convince yourself that i++ and ++i have locations — but if they did, it would just be the location of the variable i. So you might as well have just said
int *p7 = &i;
Now, you might ask, "But what if I want to take the address of i, at the same time I increment it?" And the answer is, you're just going to have to do it in two steps:
int *p7 = &i;
i++;
Yes, it's true, the i++ and ++i operators are nice in that they let you do two things at once, things like
int x = array[i++];
or
int x = *p++;
But those are useful operations, because they come up all the time when you're working with arrays. But the need to say something like
int *p5 = &(i++);
comes up much less often, I think, so it's not nearly so important to have it work. (Me, I've been programming in C for 40 years, and I don't think I've ever felt the need to grab a pointer to i and increment it at the same time.) The ++ operator is something that often comes up in a loop, as i moves through an array or something. But since the address of i doesn't change, if you need a pointer to it, It makes sense to do that just once, before the loop (or whatever) even starts.
Finally, whether you agree with my explanations so far or not, the C Standard explicitly says that the result of the ++ and -- operators is an rvalue, not an lvalue. Two compilers I just tried this on gave me the errors
error: cannot take the address of an rvalue of type 'int'
and
error: lvalue required as unary ‘&’ operand
and these error messages pretty much say the same story I've been telling.
Although, to throw a pretty big monkey wrench into this story I've been telling, the rules are evidently different in C++! You can't do &(i++), but you can do &(++i)! I think there's a good reason for this, but I don't remember what it is.
I already know the question with this answer and apologize for the initial unclear question.
In C, we cannot use &(i++) and &(++i) and I think the reason is i++ and ++i are rvalues in C. However in C++, i++ is rvalue and ++i is lvalue.
In C++, the statement
int *p1 = &(i++);
will not work as i++ returns an rvalue and you cannot take the address of an rvalue.
On the other hand, the statement
int *p2 = &(++i);
is fine (i.e., it works). Check it out here.
i++ yields the value of i before being incremented and increments it.
If &(i++) were valid, it would mean take the address of the "previous value". Since i is the name we are using for a single memory location, where would that previous value go?
If you need the previous value of i, it needs to be stored somewhere before you can do anything with it including pointing to it.
int j = i++;
int *ip = &i;
int *jp = &j;
Then, *ip will yield the incremented value and *jp will yield the value before the increment.
Since ++i yields the incremented value of i, it works with just a single value. Still, for clarity, best to use separate statements for the increment and taking the address of the variable:
int *ip = &i;
++i;
even if the compiler allows &(++i) or even if it is legal (did not check). You are writing for the fellow programmer (who might be you), not the compiler.

Internal logic of operator [] when dealing with pointers

I've been studying C++ for couple of months now and just recently decided to look more deeply into the logic of pointers and arrays. What I've been taught in uni is pretty basic - pointers contain the address of a variable. When an array is created, basically a pointer to its first element is created.
So I started experimenting a bit. (and got to a conclusion which I need confirmation for). First of all I created
int arr[10];
int* ptr = &arr[5];
And as you would imagine
cout << ptr[3];
gave me the 8th element of the array. Next I tried
int num = 6;
int* ptr2 = &num;
cout << ptr2[5];
cout << ptr2 + 5;
which to my great delight (not irony) returned the same addresses. Even though num wasn't an array.
The conclusion to which I got: array is not something special in C++. It's just a pointer to the first element (already typed that). More important: Can I think about every pointer in the manner of object of a class variable*. Is the operator [] just overloaded in the class int*? For example to be something along the lines of:
int operator[] (int index){
return *(arrayFirstaddress + index);
}
What was interesting to me in these experiments is that operator [] works for EVERY pointer. (So it's exactly like overloading an operator for all instances of the said class)
Of course, I can be as wrong as possible. I couldn't find much information in the web, since I didn't know how to word my question so I decided to ask here.
It would be extremely helpful if you explained to me if I'm right/wrong/very wrong and why.
You find the definition of subscripting, i.e. an expression like ptr2[5] in the c++ standard, e.g. like in this online c++ draft standard:
5.2.1 Subscripting [expr.sub]
(1) ... The expression E1[E2] is identical (by definition) to
*((E1)+(E2))
So your "discovery" sounds correct, although your examples seem to have some bugs (e.g. ptr2[5] should not return an address but an int value, whereas ptr2+5 is an address an not an int value; I suppose you meant &ptr2[5]).
Further, your code is not a prove of this discovery as it is based on undefined behaviour. It may yield something that supports your "discovery", but your discovery could still be not valid, and it could also do the opposite (really!).
The reason why it is undefined behaviour is that even pointer arithmetics like ptr2+5 is undefined behaviour if the result is out of the range of the allocated memory block ptr2 points to (which is definitely the case in your example):
5.7 Additive operators
(6) ... Unless both pointers point to elements of the same array
object, or one past the last element of the array object, the behavior
is undefined.
Different compilers, different optimization settings, and even slight modifications anywhere in your program may let the compiler do other things here.
An array in C++ is a collection of objects. A pointer is a variable that can store the address of something. The two are not the same thing.
Unfortunately, your sample
int num = 6;
int* ptr2 = &num;
cout << ptr2[5];
cout << ptr2 + 5;
exhibits undefined behaviour, both in the evaluation of ptr2[5] and ptr2 + 5. Pointer expressions are special - arithmetic involving pointers only has defined behaviour if the pointer being acted on (ptr2 in this case) and the result (ptr2 + 5) are within the same object. Or one past the end (although dereferencing a "one past the end" pointer - trying to access the value it points at - also gives undefined behaviour).
Semantically, *(ptr + n) and ptr[n] are equivalent (i.e. they have the same meaning) if ptr is a pointer and n is an integral value. So if evaluating ptr + n gives undefined behaviour, so does evaluating ptr[n]. Similarly, &ptr[n] and ptr + n are equivalent.
In expressions, depending on context, the name of an array is converted to a pointer, and that pointer is equal to the address of that array's first element. So, given
int x[5];
int *p;
// the following all have the same effect
p = x + 2;
p = &x[0] + 2;
p = &x[2];
That does not mean an array is a pointer though.

Understanding output of this code

This is an excercise in my textbook. I need to find the output of this code.
#include<iostream>
using namespace std;
int main()
{
int x[]={10,20,30,40,50};
int *p,**q,*t;
p=x;
t=x+1;
q=&t;
cout<<*p<<","<<**q<<","<<*t++;
return 0;
}
The output is
10,30,20
Here I dont understand the declaration of **q, and also how its value comes out to be 30. I also noticed that changing the last statement to
cout<<*p<<","<<**q<<","<<*t;
changes the output to
10,20,20
Could somebody explain what goes on behind the scenes here? Thanks a lot in advance.
Here, q is a pointer to a pointer to int, and it was set to point to t. So *q is identical to t, and **q is *t. Which means the cout expression can be rewritten as:
cout<<*p<<","<<*t<<","<<*t++;
Here you can see that t is read and modified in different parts of the expression, and the standard says that the order in which these parts are executed is not specified. So t may be modified before or after (or even while) it is read. When this kind of thing (unsequenced read and write to a variable) happens, we get undefined behavior: Anything can happen as a result. A specific compiler may give a specific result on a specific computer, but there is no guarantee that you will always get this result.
So this exercise is invalid, and there is no point in trying to figure out why you saw a specific output.
On the other hand, the second line you attempted:
cout<<*p<<","<<**q<<","<<*t;
is perfectly valid, because it doesn't modify t anywhere.
p and t are both of the type pointer to int, q is of the type pointer to (pointer to int)
The * operator makes a pointer to a reference.
So *p is of the type int&, so is *t.
*q is of the type int*& (read reference to a pointer to int)
You want to print an int value here and must therefore use the * operator a second time.
So the **q is just making a pointer to a pointer to int to a reference to int
I forgot to mention it: The process is called dereferencing pointers.
Maybe the descirption on this side will give you a better insight:
http://www.cplusplus.com/doc/tutorial/pointers/
++ operator has higher precedence than <<
When program is executed this are events:
int x[]={10,20,30,40,50};
int *p,**q,*t;
p=x;
t=x+1;
q=&t;
cout<<*p<<","<<**q<<","<<*t++; //1st change value of t to t+1,
//but return old t in place ^
//then to output stream 'p'=10, then 'q'=new 't'=old 't'+1=30,
//then old 't'=20 which is returned by sufix ++ operator

Weird output when use prefix and postfix on pointer together

Given the code below
char buf[] = "asfsf";
char *a=buf;
++*a++;
cout<<*a;
I expect the result is the next character of 's' that is 't', but the result is still 's'. Why?
Why ++*a++ is not the same as
*a++;
++*a;
cout<<*a;
Is that really a duplicate question with ++i++? I know ++i++ is a undefined behavior and will cause compile error, but ++*i++ actually can run. Is my case also a undefined behavior?
According to the language grammar, the operators associate as:
++(*a++)
Note: associativity does not imply an order of operations.
*a++ evaluates to an lvalue designating the location where a was originally pointing, with side-effect of modifying a. All fine so far.
Applying prefix-++ to that lvalue increments the value stored there (changing 'a' to 'b').
Although the two increments are unsequenced, this does not cause UB because different objects are being incremented, and the lvalue designating the latter location does not depend on the increment. (It uses the old value of a).
As it stands right now, your code has undefined behavior, because it attempts to modify the contents of a string literal.
One way (probably the preferred way) to prevent the compiler from accepting such code is to define your a like:
char const *a="asfsf";
This way, the ++*a part simply won't compile.
For the sake of exposition, let's change the code a little bit, to become:
#include <iostream>
int main(){
char x[]="asfsf";
char *a = x;
++*a++;
std::cout<<x;
}
Now a points at memory we can actually write to, and get meaningful results. This prints out bsfsf. If we print out a, we'll get sfsf.
What's happening is that a++ increments a, but still yields the original value of a. That is dereferenced, giving a reference to the first element of x. Then the pre-increment is applied to that, changing it from a to b.
If you want to increment the pointer, dereference the result, then increment that, you'd use: ++*++a;. Well, no, you wouldn't use that--or at least I hope you wouldn't. It does increment a to point at the second element of the array, then increment that second element to change it from s to t--but anybody who read the code would be completely forgiven if they hated you for writing it that way.

What does "*ptrInt ++" do?

I'm implementing a template pointer wrapper similar in functionaltiy to boost::shared_ptr.
I have a pointer to an integer ptrInt.
What I want to do: Increment the integer ptrInt points to.
My initial code was this: *ptrInt ++;, although I also tried the same using (*ptrInt) ++;
Apparently, however, this doesn't seem to do what I expected it to.
In the end I got it working using *ptrInt += 1;, however I'm asking myself:
What exactly does *ptrInt ++; do?
Is there a more elegant solution to using *ptrInt += 1;?
*p++ // Return value of object that p points to and then increment the pointer
(*p)++ // As above, but increment the object afterwards, not the pointer
*p += 1 // Add one to the object p points to
The final two both increment the object, so I'm not sure why you didn't think it worked. If the expression is used as a value, the final form will return the value after being incremented but the others return the value before.
x = (*p)++; // original value in x
(*p)++;
x = *p; // new value in X
or
x = ++*p; // increment object and store new value in x
*ptr++ equivalent to *(ptr++)
*ptrInt ++ will
increment ptrInt by 1
dereference old value of ptrInt
and (*ptrInt) ++ as well as *ptrInt += 1 will do what you want.
See Operator Precedence.
(*ptr)++ should do it, unless you are using its value right away. Use ++*ptr then, which is equivalent to ++(*ptr) due to right-to-left associativity.
On a side note, here is my smart pointer implementation, perhaps it can help you in writing your own.
The expression is evaluated using the rules for operator precedence.
The postfix version of ++ (the one where ++ comes after the variable) has a higher precedence than the * operator (indirection).
That is why *ptr++ is equivalent to *(ptr++).
You want (*ptrInt)++, which increments the object, which generally does the same as *ptrInt += 1. Maybe you have overloaded the += operator, but not the ++ operators (postfix and prefix increment operators)?
The more elegant way is whatever you tried before. i.e (*ptrInt) ++;
Since, you aren't satisfied with that, it might be because of the post - increment.
Say, std::cout<<(*ptrInt) ++; would have shown you the un-incremented value.
So, try giving ++(*ptrInt); which might behave as you expected.
*ptrInt++ in your case does increment the pointer, nothing more (before that it fetches the value from the location at throws it away. of course if you use it in a more complex expression it will use it)
(*ptrInt)++ does what you are looking for.