My value gets Wrong if I use ++ operand with my pointer - c++

My Code is:
int abdul = 11;
int *ptr = &abdul;
//Problem is here
// *ptr += 1;
// *ptr++;
cout << &*ptr;
cout << "\n" << &abdul;
cout << *ptr;
}
If I use *ptr +=1 it added 1 in abdul location value. But if I use *ptr++ it gives some random value.
When I use *ptr += 1 the output is correct. But using increment or decrement operator value gets wrong. I don't know where the problem is.

Due to operator precedence, *ptr++ is treated as *(ptr++). The pointer is incremented first and then dereferenced. In your case, that causes undefined behavior since ptr points to a single object.
To increment the value of the object that ptr points to, use (*ptr)++ or ++(*ptr).
It's better to be clear about your intention using parenthesis.

Operator precendece. *ptr++ is evaluated as *(ptr++). But you want (*ptr)++ Just add some parantheses to show the compiler what you want.

Due to the Operator Precedense what happens is you increment the address doing ptr++ and then you dereference it by doing *ptr.
what you can do is use prefix increment : ++*ptr

Related

Post-increment vs Assignment in C++ operation precedence table

I stumbled upon https://en.cppreference.com/w/cpp/language/operator_precedence
On the chart, I see that post-increment operator (++) is way above assignment operator (=).
However, I know that
int a[] = {10,20};
int* b = &a[0];
*(b++) = 5;
cout << a[0] << endl; // 5
cout << a[1] << endl; // 20
cout << *b << endl; // 20, now points to a[1]
I always take it for grant that post-increment happens after the assignment operator. However, if I follow the operation precedence chart, then isn't post-increment suppose to happen before = operation? Isn't the answer suppose to be a={10, 5} rather than a={5, 20}?
"Precedence" is misleading. It has little to do in general with evaluation order (what happens first), but instead determines what is the operand of each operator for the purpose of evaluation. But let's examine your example.
*(b++) = 5;
This means that 5 is to be assigned to the lvalue on the left. And since C++17, we know that 5 is evaluated entirely before *(b++). Prior to that, they could be evaluated in any order.
Now, b++ has the meaning of "increment b, but evaluate to its previous value". So b++ may cause the increment to happen prior to the assignment taking place, yes, but the value of (b++) is the address before the increment happened. And that is why b is updated to point at the next element, while modifying the current one, in one expression.
Post increment (b++) increments b, then returns the previous value of b.
Pre increment (++b) increments b, then returns the new value of b.
To get the behavior you're expecting, change from post-increment to pre-increment.
For example:
#include <iostream>
int main() {
int a[] = {10, 20};
int *b = &a[0];
*(++b) = 5;
std::cout << a[0] << std::endl;
std::cout << a[1] << std::endl;
std::cout << *b << std::endl;
}
Yields the following output:
10
5
5
Table is Correct. And there is no confusion for the result.
Just remember the fact that post increment(PI) or decrement(DI), perform +1 or -1 update after the current statement containing PI or DI.
*(b++) = 5;
1st b++ will take place first as it is in parentheses. but b didn't move next yet. As compiler always remember in post operations that it would perform it after the current statement. so it is like:
*b = 5; // a[0]=5; compiler remembered b=b+1; to be executed.
so now b = b+1;
hence b is now pointing at a[1];

How would ++*ptr++ be evaluated by compiler if ptr is ptr to first element of a static array?

What is the order of evaluation in ++*ptr++? Does it change when pointers and lvalues are involved in the operation?
If the precedence of a++ is higher than *a or ++a, then why is ++*a++ evaluated as first returning the incremented value then changing the pointer, rather than changing the pointer, then incrementing the value at the location.
Refrence for Precedence: https://en.cppreference.com/w/cpp/language/operator_precedence
arr = {9, 99, 999 };
int *ptr = arr;
std::cout << ++*ptr++ << '\t';
std::cout << *ptr;
I expected the output to be 100 100, but the actual output was 10 99.
The postfix increment a++ increments the pointer ptr, but returns the copy of ptr before the operation (see difference between prefix/postfix).
So it can be rewritten (as noted in Quimby's answer) as ++(*(ptr++)) and goes like:
ptr++ : increments ptr so that it points to 99, but returns another pointer that still points to 9
*ptr++ : dereferences, evaluates to 9
++*ptr++ : increments the value pointed to by the copied pointer, meaning increments 9 and returns 10
Here the logic behind pre/post increment/decrement is explained well:
Pre-increment and pre-decrement operators increments or decrements the value of the object and returns a reference to the result.
Post-increment and post-decrement creates a copy of the object, increments or decrements the value of the object and returns the copy from before the increment or decrement.
From: https://en.cppreference.com/w/cpp/language/operator_incdec
Postfix operators have higher precedence that prefix so they BIND tighter/first so: ++*ptr++ is the same as ++(*(ptr++)) which boils down to what operand works on what. So postfix ++ will be applied to your 'ptr' pointer but 'after' first std::cout line. Prefix ++ will work on dereferenced ptr so this all is the same as:
int arr[] = {9, 99, 999 };
int *ptr = arr;
++(*ptr); // 9+1=10
std::cout << *ptr << '\t';
ptr++; // now ptr points to 99
std::cout << *ptr;
In short, because ++*ptr++ is rewritten as ++(*(ptr++))
The rules in the link are quite clear:
The postfix ++ has highest precedence => ++*(ptr++)
The prefix ++ and * have the same precedence and they are right-associative => ++(*(ptr++))
The expression can also be split into individual statements like this:
arr = {9, 99, 999 };
int *ptr = arr;
int *ptr2 = ptr++;//ptr2 still points to the first element
int val = *ptr2; // 9
int incVal= ++val; // 10
Hopefully it's clear that the ptr now points to the second element of the array and the result of the expression is the incremented value.
Since you are using a single dimensional array
++*ptr referred to increment in pointer ptr to 0 elements of array, after incrementing the output for this will be 10
The postfix ++ has highest precedence => ++*(ptr++)

C++ pointer arithmetic in a loop and memory management?

I am getting started with C++. I wanted to understand the different
outputs while playing around with this snippet of code.
int main()
{
int i = 3;
int *ptr = &i; //stores address of the i
while(*(ptr)--) //the same as i--
{
cout << *ptr << endl;
}
}
When I run this code I understand that the deferenced value
of ptr, which is "i", gets 1 subtracted from it and the loop exits
when "i" equals 0. But when I use while(*ptr--) instead of while(*(ptr)--) I get a list of random integers which eventually go down to 0 and the loop breaks.
To my understanding when I use *ptr-- I am subtracting a byte(size of one int) from the initial address of &i(*ptr) with each loop. But why does the program terminate eventually? No matter what the value of "i" is, the program prints 23 random numbers with the last one being 0 and the loop exits. Should I not get an overflow error since the program runs out of memory?
However, when I use while(ptr--) the program does go into an infinite loop.
What exactly is happening?
Thank you very much.
(ptr) is the same as ptr, thus (ptr)-- is the same as ptr--.
*ptr-- IS NOT the same as i-- !
You are applying operator-- to the right side of the pointer. The suffix/postfix operator-- has a higher precedence than operator*. So, *ptr-- is the same as *(ptr--), not (*ptr)-- like you are expecting.
IOW, ptr-- gets evaluated first, which returns a copy of the current pointer and then decrements the pointer, and then you are dereferencing the copied pointer to retrieve the value that was previously being pointing at.
That is why you are seeing garbage - you are decrementing the pointer into memory that does not belong to you.
To simply decrement the int and not the pointer, use (*ptr)-- instead. IOW, dereference the pointer first, then decrement the value being pointed at, eg:
int main()
{
int i = 3;
int *ptr = &i; //stores address of the i
while((*ptr)--) //the same as i--
{
cout << *ptr << endl;
}
}
Live demo
Parenthesis and operator precedence matter!

Why it doesn't yield memory-addresses when looping through a pointer?

When we print ptr, it gives a memory address, but when we loop through it, we get array elements. What's causing the difference & why so?
int main()
{
string texts[] = { "one", "two", "three" };
string* ptr = texts;
for (int i = 0; i < 3; i++) {
cout << ptr[i];
}
_getch();
return 0;
}
When we print ptr, it gives a memory address, but when we loop through it, we get array elements.
ptr is a pointer so when you print it you get a memory address.
Note ptr[i] is the same as *(ptr + i). So when you loop using array syntax ptr[i] you are dereferencing it and so you get the data itself.
The type of ptr is string* - a pointer to a string. The type of ptr[i] is string.
cout is a global instance of class ostream. This class defines an insertion operator, i.e. operator<<() for string objects which specifically prints the contents of the string. Therefore cout << ptr[i] prints the text. On the other hand, ostream does not specifically define an insertion operator for pointers to strings. So the closest matching definition is operator<<(void*) - an insertion operator for pointers in general. This just prints the address.
ptr[i] is the same as *(ptr + i).
a container object like a string or an array is a pointer to the first element in that container. the [] operator access a certain object based on the starting location like #artm said. this question is the result of a lack of understanding how variable memory allocation works. look into that for a more complete answer.
When you write string* ptr= texts; the starting address of the array is stored in the pointer memory i.e. the pointer now points to the starting address of the array. So, whenever you'll print ptr, an address will be printed.
But when you loop through it i.e. ptr[I] it's evaluated as *(ptr+i). * is the dereferencing operator which means it gives the value stored at the address given to it. Therefore, *(ptr+i) becomes the_value_at(location saved in ptr + i more units). Which is why you get array values.

I cannot change the value of an integer using pointer

Here is the code I'm running:
#include <iostream>
using namespace std;
int main()
{
int x = 5;
int *p;
p = &x;
*p++;
cout<<x<<endl;
return 0;
}
The output should be 6, because p is pointing at the address of x. However, I get 5.
But more interestingly, I couldn't understand why the output is 6 when I change *p++ with *p = *p+1. Why is this?
You are wrong. *p++ reads the value that p points to, then increases the pointer p. You probably wanted (*p)++.
*p = *p + 1 works because it is correct.
Postfix ++ has higher precedence than unary *, so *p++ is parsed as *(p++); IOW, you're incrementing the pointer, not the thing being pointed to.
Use (*p)++ to increment the thing being pointed to, or use ++*p.
Use brackets if you do not understand operator precedence.
*p++
is
*(p++)
and you want
(*p)++
The rule of thumb is:
multiplication and division go before addition and subtraction
for everything else, just use brackets