Can someone help me understand this? int *& pr [duplicate] - c++

This question already has answers here:
What does *& mean in a function parameter
(5 answers)
Closed 10 years ago.
I found this in a final exam:
int a = 564;
int* pa = &a;
int *& pr = pa;
cout << *pr;
According to the multiple choice answer, the code is valid, and displays the value of a.
But I'm confused about evaluation and precedence for line 3. Order of operations for C states that * and & have the same order. So, would it then be int *(&pr)? How can this be described in words?
Thank you.

The third line defines a pointer reference (or a reference to a pointer, if you want). Assigning it to a pointer makes pr to actually be an alias to pa, and when evaluated, it points where pa points to, that is, a.
In the declaration of a variable, * and & don't have the meaning of operators, so precedence doesn't make sense here.

It's a reference to a pointer. In C, you would express that as a pointer to a pointer.
You could write something like this:
// C++ style
void update_my_ptr(int*& ptr) { ptr = new int[1024]; }
// C style
void update_my_ptr_c(int **ptr) { *ptr = malloc(1024 * sizeof(int)); }
int main()
{
int *ptr;
update_my_ptr(ptr);
// Here ptr is allocated!
}

Line three creates a reference (read: alias) of a pointer to an int. If you were to set pr to 0, pa would also be equal to 0 (and vice-versa).

Related

Why does increment operator (++) not work when you reference using pointers in cpp/c [duplicate]

This question already has answers here:
How to increment a pointer address and pointer's value?
(5 answers)
Closed 2 years ago.
I was writing a code related to referencing in C/C++. I made a pointer and put it into a function that incremented it. In the function, I wrote *ptr++ and tried to increment the value of the integer the pointer was pointing at.
#include <iostream>
using namespace std;
void increment(int *ptr)
{
int &ref = *ptr;
*ptr++; // gets ignored?
ref++;
}
int main()
{
int a = 5;
increment(&a);
cout << a;
return 0;
}
Can anyone please tell me why I can't increment the variable? I have tried incrementing it using +=1, and it works but not by using ++ operator?
++ has higher precedence than *, so *ptr++ is treated as *(ptr++). This increments the pointer, not the number that it points to.
To increment the number, use (*ptr)++.
Your code is:
*ptr++;
Which is equivalent to:
*(ptr++);
Which means pointer is incremented first and then dereferenced. this happens because increment operator ++ has higher precedence than dereferance operator * . So you should use:
(*ptr)++;
Here first pointer is dereferenced then incremented.

what's the difference between these two pointer code [duplicate]

This question already has answers here:
Pointer vs. Reference
(12 answers)
Closed 6 years ago.
I found these two different sources, but they do the exact same thing. I was wondering if there is a difference or not but I couldn't figure it out.
Can anyone tell me the difference and when should I use which?
this is the first one:
void function1(int *x) {
*x = 100;
}
int main() {
int var1 = 10;
function1(&var1);
cout << var1 << endl;
}
and this is the second one:
void function2(int &x) {
x = 100;
}
int main() {
int var2 = 10;
function2(var2);
cout << var2 << endl;
}
int *x is a pointer whereas int &x is a reference. Probably the biggest difference is that you can't change where reference is pointing to.
The first is a pointer, the second is a reference. The ideas have some similarities, but there are also differences.
A pointer is a C and C++ mechanism and a bit more "pure" but gives you more posibilies for advanced concepts like pointer arithmetics. References are C++ only and are more safe and more implicit, as a reference is used with the same syntax as a normal varible while using the referenced one. A pointer is more explicit if you want to use or change its value, as you have to explicitely dereference it using *var, and explicitely have obtain it.

What does ** mean in C++? [duplicate]

This question already has answers here:
Uses for multiple levels of pointer dereferences?
(17 answers)
Pointer to a pointer to a pointer [duplicate]
(4 answers)
Closed 8 years ago.
For example:
bool insertInFront( IntElement **head, int data ){
IntElement *newElem = new IntElement;
if ( !newElem ) return false;
newElen->data = data;
*head = newElem; // Correctly updates head
return true;
}
I am new to C++, coming from Java. I get the * for indirection syntax, but ** is not listed on this page: http://en.wikipedia.org/wiki/Operators_in_C_and_C++#Member_and_pointer_operators
I found this example on page 28 of Programming Interviews Exposed
Update
I realize that this question is naive, and I probably could have found an answer through other means. Obviously, I am new to the language. Still, asking "What does ** mean?" is not well supported online for someone who does not know that ** is a pointer operation. There are very few relevant results when searching C ** syntax or C++ ** meaning. Additionally, using ctrl + f to search ** in the wiki page above, and other documentation, doesn't return any matches at all.
I just wanted to clarify, from a beginner's perspective, that this question is hard to distinguish from the duplicates. Of course, the answer is the same :-) Thank you for the help.
There is no specific ** operator in C++, instead it's two separate asterisks, and asterisks in a declaration denotes pointer declaration.
So in the declaration
IntElement **head
the argument head is declared to be a pointer to a pointer to IntElement.
Its meaning:
int a; // integer
int *ptrA = &a // pointer to a integer
int **PtrPtrA = &ptrA // point to pointer to a integer
How can it be used:
void function_nochange(int *pA ) { pA = &b; }
void function_change (int **ppA) { *ppA = &b; }
int a;
int b;
void test()
{
int *ptrA = &a
function_nochange(ptrA)
// here ptrA still point to int a since ptrA was copied
function_change(&ptrA)
// here ptrA point to int b since ptrA was passed as pointer
}
**VariableName means pointer to pointer(a chain of pointers) in C++
You can find good tutorials here :
http://www.tutorialspoint.com/cplusplus/cpp_pointer_to_pointer.htm
http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer

Why pointer to pointer?

A very general question: I was wondering why we use pointer to pointer?
A pointer to pointer will hold the address of a pointer which in turn will point to another pointer. But, this could be achieved even by using a single pointer.
Consider the following example:
{
int number = 10;
int *a = NULL;
a = &number;
int *b = a;
int *pointer1 = NULL;
pointer1 = b; //pointer1 points to the address of number which has value 10
int **pointer2 = NULL;
pointer2 = &b; //pointer2 points to the address of b which in turn points to the address of number which has value 10. Why **pointer2??
return 0;
}
I think you answered your own question, the code is correct, what you commented isn't.
int number = 10; is the value
int *pointer1 = b; points to the address where int number is kept
int **pointer2 = &b; points to the address where address of int number is kept
Do you see the pattern here??
address = * (single indirection)
address of address = ** (double indirection)
The following expressions are true:
*pointer2 == b
**pointer2 == 10
The following is not!
*pointer2 == 10
Pointer to pointer can be useful when you want to change to what a pointer points to outside of a function. For example
void func(int** ptr)
{
*ptr = new int;
**ptr = 1337;
}
int main()
{
int* p = NULL;
func(&p);
std::cout << *p << std::endl; // writes 1337 to console
delete p;
}
A stupid example to show what can be achieved :) With just a pointer this can not be done.
First of all, a pointer doesn't point to a value. It point to a memory location (that is it contains a memory address) which in turn contains a value. So when you write
pointer1 = b;
pointer1 points to the same memory location as b which is the variable number. Now after that is you execute
pointer2 = &b;
Then pointer2 point to the memory location of b which doesn't contains 10 but the address of the variable number
Your assumption is incorrect. pointer2 does not point to the value 10, but to the (address of the) pointer b. Dereferencing pointer2 with the * operator produces an int *, not an int.
You need pointers to pointers for the same reasons you need pointers in the first place: to implement pass-by-reference parameters in function calls, to effect sharing of data between data structures, and so on.
In c such construction made sense, with bigger data structures. The OOP in C, because of lack of possibility to implement methods withing structures, the methods had c++ this parameter passed explicitly. Also some structures were defined by a pointer to one specially selected element, which was held in the scope global to the methods.
So when you wanted to pass whole stucture, E.g. a tree, and needed to change the root, or 1st element of a list, you passes a pointer-to-a-pointer to this special root/head element, so you could change it.
Note: This is c-style implementation using c++ syntax for convienience.
void add_element_to_list(List** list, Data element){
Data new_el = new Data(element); // this would be malloc and struct copy
*list = new_el; //move the address of list, so it begins at new element
}
In c++ there is reference mechanismm and you generally you can implement nearly anything with it. It basically makes usage of pointers at all obsolete it c++, at least in many, many cases. You also design objects and work on them, and everything is hidden under the hood those two.
There was also a nice question lately "Why do we use pointers in c++?" or something like that.
A simple example is an implementation of a matrix (it's an example, it's not the best way to implement matrices in C++).
int nrows = 10;
int ncols = 15;
double** M = new double*[nrows];
for(unsigned long int i = 0; i < nrows; ++i)
M[i] = new double[ncols];
M[3][7] = 3.1416;
You'll rarely see this construct in normal C++ code, since C++ has references. It's useful in C for "passing by reference:"
int allocate_something(void **p)
{
*p = malloc(whatever);
if (*p)
return 1;
else
return 0;
}
The equivalent C++ code would use void *&p for the parameter.
Still, you could imagine e.g. a resource monitor like this:
struct Resource;
struct Holder
{
Resource *res;
};
struct Monitor
{
Resource **res;
void monitor(const Holder &h) { res = &h.res; }
Resource& getResource() const { return **res; }
}
Yes, it's contrived, but the idea's there - it will keep a pointer to the pointer stored in a holder, and correctly return that resource even when the holder's res pointer changes.
Of course, it's a dangling dereference waiting to happen - normally, you'd avoid code like this.

a bit of confusion over pointers (void ones) and functions [duplicate]

This question already has answers here:
Function does not change passed pointer C++
(4 answers)
Closed 8 years ago.
so right now i am trying to do some nift code for a little game i am making and I've run into something that has been bothering me for a while about pointers.
but first things first, i am trying to have a function take in a void* and give that void* a value, but it seems to not actually stay beyond the function like i'm used to. so...
void ItemGen(void* Holder){
Item* NewItem
NewItem = new Item*
NewItem->Init();
Holder = NewItem;
}
it's not actually making "items" but various kinds of items that inherit from a item, this is just me making it simpler.
Holder gets changed but never make it outside the function, how should i change this, so that it does.
on top of that, i am sort of confused about a certain occurrence that can happen and i just want to know what happens when you do these. or really the difference between them
void *p1;
void *p2;
&p1 = &p2;
p1 = p2;
*p1 = *p2;
oh and is there a way to do a XOR operation on pointers so i can swap them with out a holding pointer.
i feel like i asked very stupid questions, but are confusing simply because they're void *'s.
Pointers are variables like any other, and as such are passed by value to functions. You've simply assigned a new value to the parameter copy of your pointer.
If you want to change a variable you pass to a function you must pass by reference or by pointer. Preferably the former.
void ItemGen(void *& Holder);
BTW, that's a horrible naming convention.
I am answering this point "Holder gets changed but never make it outside the function, how should i change this, so that it does."
void ItemGen(Item** Holder){
Item* NewItem
NewItem = new Item*
NewItem->Init();
*Holder = NewItem;
}
void someotherfunc() {
Holder * holder=0;
ItemGen(&holder)
if(holder!=0) {
holder->dosomething()
}
}
"void" simply means "nothing". A "void*" pointer points to nothing in particular. It's a way of saying "I don't know what kind of thing this pointer points to"; a void* pointer is a catch all that can receive any kind of pointer, but if you want to go from a void* pointer to any other kind, you have to explicitly cast it.
As to your first problem:
If you lived at "1234 Pointer Street", there is nothing magical about the number "1234", it's just a number. It only tells you anything when you treat it as a "pointer" - a house number. It "points" to a house on a particular street.
In the case of a computer, the street is memory.
int a = 0;
int* b = 0;
the variables "a" and "b" both contain the numeric value "0".
b = b + 1;
See? perfectly valid. So
void foo(int a, int* b)
{
a = a + 1;
b = b + 1;
}
void bar()
{
int x = 0;
int* y = 0;
foo(x, y);
// 'x' and 'y' are still zero here, they have to be, or you couldn't do
foo(0, 0);
}
Pointers to have some distinguishing features from regular variables.
int a = 0;
int* b = 0;
a = a + 1; // now a = 1
b = b + 1; // now b = b + sizeof(int) => 4.
What pointers do best is provide values for C/C++'s "dereference" operators.
a = *(b);
Going back to the streets example, if we assigned b our "1234 Pointer Street" address, it would be:
b = 1234;
What if we wanted to deliver something there?
*b
This means: The contents of the address that b describes.
Lets go back to the definition
int* b;
This says: "b is the address of an integer". How do we get the address of a specific integer?
// imagine a set of mailboxes.
int box1, box2, box3, box4, box5;
// lets put something interesting into box 3.
box3 = 5;
// now let's address somethign to box3.
// "&" is the "address of" operator.
int* pointer = &box3;
// now lets put something more interesting in pointer.
pointer = 10;
// whoops - that was wrong, we just changed the ADDRESS to some random numeric value.
// what we mean't was:
*pointer = 10;
printf("box 3 contains %d\n", box3);
// answer? 10, not 5.
After setting "pointer = &box3" we populated "pointer" with the location of box3's storage in memory, so when we wrote to that address using "*pointer = 10" we wrote to the storage address of box3.
You asked about
void *p1;
void *p2;
&p1 = &p2;
p1 = p2;
*p1 = *p2;
"&p1 = &p2" says "the address of p1 is the address of p2" and isn't legal, it wouldn't compile.
"p1 = p2" is legal, but it says "assign the same address as p2 to p1"
"*p1 = *p2" is illegal because you are using void pointers, which point to void, besides, you've just made p1 and p2 be equal to each other so it would be a null operation.
To fix your initial problem, you would need to provide a way for the caller to receive the new value you are creating.
Option 1: Accept a pointer-to-pointer
This is the very old-school C way to do it, but your code doesn't look very C++ so far so I'll list it first.
void ItemGen(void** Holder)
{
Item* NewItem = new Item;
NewItem->Init(); // why doesn't the constructor do this?
// ** means pointer to storage that is itself also a pointer,
// so if we dereference it once we will be refering to the inner pointer.
*Holder = NewItem;
}
Option 2: Return a pointer
void* ItemGen() // Why isn't this "Item*"?
{
Item* NewItem = new Item;
NewItem->Init();
return NewItem;
}
Option 3: Take a reference
void ItemGen(Item*& Holder)
{
Holder = new Item;
Holder->Init();
}
This says "Holder is a reference to a pointer to storage of type Item". It's exactly like a "Item*" pointer except instead of creating a temporary local copy of the value passed in, it's an alias for the value that was passed in.
If you absolutely have to throw away the type information of your pointer:
void ItemGen(void*& Holder)
{
Item* NewItem = new Item;
NewItem->Init();
Holder = NewItem;
}
At the level you appear to be with C++ so far, I would guess that your use of void* pointers is probably misguided.