UPDATE: I think I have done well in my exam; thanks for everyone's help and hope you have a nice week(end)!
I am currently revising pointers for my C++ exam and came across an example that I still cannot comprehend.
Consider the following (partial) code:
int x = 17;
int *ptr = &x;
cout<<*&ptr<<" "<<&ptr<<" "<<ptr<<" "<<*ptr<<endl;
I understand that &ptr and ptr are the same, i.e. that print the address of variable x. I also understand that *ptr prints out the value inside variable x, i.e. 17.
However, I cannot understand the first one, i.e. *&ptr. It prints an address, but I do not know to which it points to. I have tried researching it, but I did not find much on it. What does the *& combination represent?
ptr and &ptr are not the same. &ptr is the address of ptr (i.e., a pointer to a pointer).
* is the dereference operator - it returns the value the pointer points to. So, if you dereference &ptr, you're asking for "the value that the address of ptr is pointing to", or ptr (which, of course, is in turn, the address of x).
in *&ptr expression, operator precedence is the same for * and for & (but precedence is from right to left). So it just takes address of ptr (stack address), but then dereferences it, basically that is equivalent to just ptr.
You have (fantasy memory addresses):
variable value address
x 17 0x0001
ptr == &x 0x0001 0x0002
* dereferences a pointer. For example *ptr uses the value of ptr which is 0x0001 and looks what value it find at that address: 17.
& on the other hand is the address-of operator. &x is the address of x, it is 0x0001. The address of x is ptr.
&*ptr is just ptr.
I understand that &ptr and ptr are the same ...
No they are not. ptr is the address of x (0x0001). &ptr is the address of ptr (0x0002).
One thing that is maybe not so clear from other answers: in an expression like *&ptr, the dereference operator * does the inverse operation of the "address_of" operator &, so that they effectively cancel out when combined, and the result is that *&ptr is identical to ptr.
A simple way to think about this is to consider the operation of halving a number (i.e. dividing it by 2) and doubling it (multiplying it by 2). Take any number x: if you halve it and then double the result, what do you get? You get x back, of course, because those two operations cancel out. You are starting from a value, applying a function to it, and then applying its inverse function, so that you end up with the original value.
& and * work the same way: you have a variable ptr with its value, you take the address of that variable with &, and then * takes that address and gives you the value that is stored there, which is the value of ptr.
This means that *&ptr is identical to ptr, and you can do this *& trick it as many times as you want: it would be the same if you wrote *&*&*&*&*&ptr. In case you are wondering, all these operators are evaluated from right to left, because that's what the table of precedence and associativity says (they have the same precedence, 2, and when you have multiple operators with the same precedence you apply them in the order specified by the associativity).
Related
I have a question about incrementing in pointers that I dont quite understand.
Lets see 2 small programs:
int iTuna=1;
int* pPointer= &iTuna;
*pPointer = *pPointer + 1 ; //Increment what pPointer is pointing to.
cout << iTuna << endl;
In this first program I increment what pPointer is pointing to like this "*pPointer = *pPointer +1".
And as I expected iTuna changed to "2" and the program printed out the value "2"
int iTuna=1;
int* pPointer= &iTuna;
*pPointer++; //Increment what pPointer is pointing to.
cout << iTuna << endl;
system("PAUSE");
return 0;
Here I incremented incremented what pPointer is pointing to this was "*pPointer++". But here iTuna stays as "1" and the programs prints out the value "1" .
Although I expected this one to work as the first, it didn't.
Please Help me and tell me why the second peice of code isn't working like I expected and how to get around it.
Thank You
*pPointer++;
is equivalent to
*pPointer;
pPointer++;
so it increments the pointer, not the dereferenced value.
You may see this from time to time in string copy implementations like
while(*source)
*target++ = *source++;
Since your problem is a matter of operator precedence, if you want to deref the pointer, and then increment, you can use parens:
(*pointer)++;
++ operator precedence is higher than *d dereference.
What you write is actually
*(p++)
However you should use
(*p)++
*ptr++; - increment pointer and dereference old pointer value
It's equivalent to:
*(ptr_p++) - increment pointer and dereference old pointer value
Here is how increment the value
(*ptr)++; - increment value
That's becuase ++ has greater precedence than *, but you can control the precedence using ()
In the Second program you are not increasing the the content at the pPointer address, but you are increasing the pointer. So suppose here if the pPointer value(memmory location allocated to iTuna) is 1000 then it will increase the location to 1000+2(int size)=1002 not the content to 1+1=2. And In the above program you are accessing the pointer location contents. Thats why you are not getting the expected results
*pPointer++; - Here dereference operator(*) has more precedence than increment operator(++). So this statement is first dereferencing and incrementing the pointer. After this you are printing the value of iTuna which will give you the same value. You are not printing the value by dereferencing pointer variable(*pPointer), because this will leads to crash(undefined behaviour). Because pPointer is now incremented.
Use like (*pPointer)++; to increment the value which is pointed by pPointer.
To get clear idea print the address stored in pPointer variable before and after your increment statement.
In the first case, the content of the pointer is incremented because *pPointer correspond to the content of the variable iTuna.
In the second one, the content is not incremented because you pPointer incrementing the pointer address. Remembering operator precedence rules, postfix operators such as increment (++) and decrement (--), have higher precedence than prefix operators, such as the dereference operator (*). Therefore, writting
*pPointer++
is equivalent to
*(pPointer++)
And what it does is to increase the value of pPoiner (so it now points to the next element), but because ++ is used as postfix, the whole expression is evaluated as the value pointed originally by the pointer (the address it pointed to before being incremented).
The correct code to have what you are expecting for is the following:
++*pPointer
or
(*pPointer)++
What is the purpose of the parentheses in the following piece of code? What would be happening if the parentheses were not there? Sorry, I am new to C++.
void foo(int * xPtr) {
(*xPtr)++;
}
With the parentheses, you increment the object the pointer is referencing, without them, you are incrementing the pointer to the next memory address and THEN dereferencing it (which in this case would do nothing).
If parentheses are not there then you are basically modifying the memory address stored inside xPtr and then dereferencing the pointer. So clearly this is not what is desired.
Say we want the value stored at memory location 1000 to be incremented, but
*xPtr++;
results in incrementing the memory location by 4 and then,value at memory location 1004 is accessed, assuming size of integer on the machine is 4 bytes.
(*xPtr)++ will increment the thing xPtr points to.
Postfix ++ has higher precedence than unary *; without parentheses, the code would be parsed as *(xPtr++) - you're incrementing xPtr, not the thing xPtr points to.
I am dynamically creating 3 objects of MyClass.
MyClass *ptr = new MyClass[3];
I'm assuming ptr is the address of the first instance of said object. I can do
(*ptr).doStuff();
However, when I try to access the 2nd object, via
(* (ptr + sizeof(MyClass)) ).doStuff();
It throws an exception. How am I supposed to get at the other objects?
Here are the options (from most recommended to least recommended):
ptr[1].doStuff();
(ptr+1)->doStuff();
(*(ptr+1)).doStuff();
((MyClass*)((char*)ptr+sizeof(MyClass)))->doStuff();
(*(MyClass*)((char*)ptr+sizeof(MyClass))).doStuff();
The valid code will look as
(* (ptr + 1) ).doStuff();
This is so-called the pointer arithmetic. You "shift" the pointer to the number of elements you want.
That's because incrementing ptr by 1 does not simply increment the pointer by 1 byte. Instead, it moves the pointer so far as to point to the next element to the array. Instead of your final line you have to write
(* (ptr + 1) ).doStuff();
or:
(ptr+1)->doStuff();
or, even more readable, as the commenters have suggested:
ptr[1]->doStuff();
Pointer arithmetic already takes the size of the pointee type into account. So you should plus 1, not sizeof(MyClass).
Otherwise you are plussing too far.
I have a question about incrementing in pointers that I dont quite understand.
Lets see 2 small programs:
int iTuna=1;
int* pPointer= &iTuna;
*pPointer = *pPointer + 1 ; //Increment what pPointer is pointing to.
cout << iTuna << endl;
In this first program I increment what pPointer is pointing to like this "*pPointer = *pPointer +1".
And as I expected iTuna changed to "2" and the program printed out the value "2"
int iTuna=1;
int* pPointer= &iTuna;
*pPointer++; //Increment what pPointer is pointing to.
cout << iTuna << endl;
system("PAUSE");
return 0;
Here I incremented incremented what pPointer is pointing to this was "*pPointer++". But here iTuna stays as "1" and the programs prints out the value "1" .
Although I expected this one to work as the first, it didn't.
Please Help me and tell me why the second peice of code isn't working like I expected and how to get around it.
Thank You
*pPointer++;
is equivalent to
*pPointer;
pPointer++;
so it increments the pointer, not the dereferenced value.
You may see this from time to time in string copy implementations like
while(*source)
*target++ = *source++;
Since your problem is a matter of operator precedence, if you want to deref the pointer, and then increment, you can use parens:
(*pointer)++;
++ operator precedence is higher than *d dereference.
What you write is actually
*(p++)
However you should use
(*p)++
*ptr++; - increment pointer and dereference old pointer value
It's equivalent to:
*(ptr_p++) - increment pointer and dereference old pointer value
Here is how increment the value
(*ptr)++; - increment value
That's becuase ++ has greater precedence than *, but you can control the precedence using ()
In the Second program you are not increasing the the content at the pPointer address, but you are increasing the pointer. So suppose here if the pPointer value(memmory location allocated to iTuna) is 1000 then it will increase the location to 1000+2(int size)=1002 not the content to 1+1=2. And In the above program you are accessing the pointer location contents. Thats why you are not getting the expected results
*pPointer++; - Here dereference operator(*) has more precedence than increment operator(++). So this statement is first dereferencing and incrementing the pointer. After this you are printing the value of iTuna which will give you the same value. You are not printing the value by dereferencing pointer variable(*pPointer), because this will leads to crash(undefined behaviour). Because pPointer is now incremented.
Use like (*pPointer)++; to increment the value which is pointed by pPointer.
To get clear idea print the address stored in pPointer variable before and after your increment statement.
In the first case, the content of the pointer is incremented because *pPointer correspond to the content of the variable iTuna.
In the second one, the content is not incremented because you pPointer incrementing the pointer address. Remembering operator precedence rules, postfix operators such as increment (++) and decrement (--), have higher precedence than prefix operators, such as the dereference operator (*). Therefore, writting
*pPointer++
is equivalent to
*(pPointer++)
And what it does is to increase the value of pPoiner (so it now points to the next element), but because ++ is used as postfix, the whole expression is evaluated as the value pointed originally by the pointer (the address it pointed to before being incremented).
The correct code to have what you are expecting for is the following:
++*pPointer
or
(*pPointer)++
Embarrassing though it may be I know I am not the only one with this problem.
I have been using C/C++ on and off for many years. I never had a problem grasping the concepts of addresses, pointers, pointers to pointers, and references.
I do constantly find myself tripping over expressing them in C syntax, however. Not the basics like declarations or dereferencing, but more often things like getting the address of a pointer-to-pointer, or pointer to reference, etc. Essentially anything that goes a level or two of indirection beyond the norm. Typically I fumble with various semi-logical combinations of operators until I trip upon the correct one.
Clearly somewhere along the line I missed a rule or two that simplifies and makes it all fall into place. So I guess my question is: do you know of a site or reference that covers this matter with clarity and in some depth?
I don't know of any website but I'll try to explain it in very simple terms. There are only three things you need to understand:
variable will contain the contents of the variable. This means that if the variable is a pointer it will contain the memory address it points to.
*variable (only valid for pointers) will contain the contents of the variable pointed to. If the variable it points to is another pointer, ptr2, then *variable and ptr2 will be the same thing; **variable and *ptr2 are the same thing as well.
&variable will contain the memory address of the variable. If it's a pointer, it will be the memory address of the pointer itself and NOT the variable pointed to or the memory address of the variable pointed to.
Now, let's see a complex example:
void **list = (void **)*(void **)info.List;
list is a pointer to a pointer. Now let's examine the right part of the assignment starting from the end: (void **)info.List. This is also a pointer to a pointer.
Then, you see the *: *(void **)info.List. This means that this is the value the pointer info.List points to.
Now, the whole thing: (void **)*(void **)info.List. This is the value the pointer info.List points to casted to (void **).
I found the right-left-right rule to be useful. It tells you how to read a declaration so that you get all the pointers and references in order. For example:
int *foo();
Using the right-left-right rule, you can translate this to English as "foo is a function that returns a pointer to an integer".
int *(*foo)(); // "foo is a pointer to a function returning a pointer to an int"
int (*foo[])(); // "foo is an array of pointers to functions returning ints"
Most explanations of the right-left-right rule are written for C rather than C++, so they tend to leave out references. They work just like pointers in this context.
int &foo; // "foo is a reference to an integer"
Typedefs can be your friend when things get confusing. Here's an example:
typedef const char * literal_string_pointer;
typedef literal_string_pointer * pointer_to_literal_string_pointer;
void GetPointerToString(pointer_to_literal_string_pointer out_param)
{
*out_param = "hi there";
}
All you need to know is that getting the address of an object returns a pointer to that object, and dereferencing an object takes a pointer and turns it into to object that it's pointing to.
T x;
A a = &x; // A is T*
B b = *a; // B is T
C c = &a; // C is T**
D d = *c; // D is T*
Essentially, the & operator takes a T and gives you a T* and the * operator takes a T* and gives you a T, and that applies to higher levels of abstraction equally e.g.
using & on a T* will give you a T**.
Another way of thinking about it is that the & operator adds a * to the type and the * takes one away, which leads to things like &&*&**i == i.
I'm not sure exactly what you're looking for, but I find it helpful to remember the operator precedence and associativity rules. That said, if you're ever confused, you might as well throw in some more parens to disambiguate, even if it's just for your benefit and not the compiler's.
edit: I think I might understand your question a little better now. I like to think of a chain of pointers like a stack with the value at the bottom. The dereferencing operator (*) pops you down the stack, where you find the value itself at the end. The reference operator (&) lets you push another level of indirection onto the stack. Note that it's always legal to move another step away, but attempting to dereference the value is analogous to popping an empty stack.