C++ Understanding Pointer Passing and Scope [duplicate] - c++

I have my function and I am filling targetBubble there, but it is not filled after calling this function, but I know it was filled in this function because I have there output code.
bool clickOnBubble(sf::Vector2i & mousePos, std::vector<Bubble *> bubbles, Bubble * targetBubble) {
targetBubble = bubbles[i];
}
And I am passing the pointer like this
Bubble * targetBubble = NULL;
clickOnBubble(mousePos, bubbles, targetBubble);
Why it is not working?

Because you are passing a copy of pointer. To change the pointer you need something like this:
void foo(int **ptr) //pointer to pointer
{
*ptr = new int[10]; //just for example, use RAII in a real world
}
or
void bar(int *& ptr) //reference to pointer (a bit confusing look)
{
ptr = new int[10];
}

You are passing the pointer by value.
Pass a reference to the pointer if you want it updated.
bool clickOnBubble(sf::Vector2i& mousePos, std::vector<Bubble *> bubbles, Bubble *& t)

if you write
int b = 0;
foo(b);
int foo(int a)
{
a = 1;
}
you do not change 'b' because a is a copy of b
if you want to change b you would need to pass the address of b
int b = 0;
foo(&b);
int foo(int *a)
{
*a = 1;
}
same goes for pointers:
int* b = 0;
foo(b);
int foo(int* a)
{
a = malloc(10); // here you are just changing
// what the copy of b is pointing to,
// not what b is pointing to
}
so to change where b points to pass the address:
int* b = 0;
foo(&b);
int foo(int** a)
{
*a = 1; // here you changing what b is pointing to
}
hth

You cannot change the pointer unless you pass it by (non const) reference or as a double pointer. Passing by value makes a copy of the object and any changes to the object are made to the copy, not the object. You can change the object that the pointer points to, but not the pointer itself if you pass by value.
Have a read of this question to help understand the differences in more detail When to pass by reference and when to pass by pointer in C++?

Related

Write Access Violation (ptr was nullptr) while returning a pointer in a function that was used to create a dynamic array [duplicate]

I have my function and I am filling targetBubble there, but it is not filled after calling this function, but I know it was filled in this function because I have there output code.
bool clickOnBubble(sf::Vector2i & mousePos, std::vector<Bubble *> bubbles, Bubble * targetBubble) {
targetBubble = bubbles[i];
}
And I am passing the pointer like this
Bubble * targetBubble = NULL;
clickOnBubble(mousePos, bubbles, targetBubble);
Why it is not working?
Because you are passing a copy of pointer. To change the pointer you need something like this:
void foo(int **ptr) //pointer to pointer
{
*ptr = new int[10]; //just for example, use RAII in a real world
}
or
void bar(int *& ptr) //reference to pointer (a bit confusing look)
{
ptr = new int[10];
}
You are passing the pointer by value.
Pass a reference to the pointer if you want it updated.
bool clickOnBubble(sf::Vector2i& mousePos, std::vector<Bubble *> bubbles, Bubble *& t)
if you write
int b = 0;
foo(b);
int foo(int a)
{
a = 1;
}
you do not change 'b' because a is a copy of b
if you want to change b you would need to pass the address of b
int b = 0;
foo(&b);
int foo(int *a)
{
*a = 1;
}
same goes for pointers:
int* b = 0;
foo(b);
int foo(int* a)
{
a = malloc(10); // here you are just changing
// what the copy of b is pointing to,
// not what b is pointing to
}
so to change where b points to pass the address:
int* b = 0;
foo(&b);
int foo(int** a)
{
*a = 1; // here you changing what b is pointing to
}
hth
You cannot change the pointer unless you pass it by (non const) reference or as a double pointer. Passing by value makes a copy of the object and any changes to the object are made to the copy, not the object. You can change the object that the pointer points to, but not the pointer itself if you pass by value.
Have a read of this question to help understand the differences in more detail When to pass by reference and when to pass by pointer in C++?

Function with pointer as parameter - what does the function expect by calling?

I saw this example:
void pass_by_value(int* p)
{
//Allocate memory for int and store the address in p
p = new int;
}
void pass_by_reference(int*& p)
{
p = new int;
}
int main()
{
int* p1 = NULL;
int* p2 = NULL;
pass_by_value(p1); //p1 will still be NULL after this call
pass_by_reference(p2); //p2 's value is changed to point to the newly allocate memory
return 0;
}
if i call the function pass-by-value, shouldnt it expect something like "&p" instead of p?
The pass-by-value is messed up anyway, the value passed to the function would be lost when the call completes and the memory would leak. It's legal code, it's just useless. If not using references or function return value the function would need to take a pointer-to-pointer (really, the compiler is likely to produce the same code for both the pointer-to-pointer and reference-to-pointer cases - barring inlining - it's just a bit cleaner to use the reference):
void foo(int ** p)
{
*p = new int;
}
int main()
{
int * p = nullptr;
foo(&p);
delete p;
}

Inserting NULL root into Binary Search Tree [duplicate]

I have my function and I am filling targetBubble there, but it is not filled after calling this function, but I know it was filled in this function because I have there output code.
bool clickOnBubble(sf::Vector2i & mousePos, std::vector<Bubble *> bubbles, Bubble * targetBubble) {
targetBubble = bubbles[i];
}
And I am passing the pointer like this
Bubble * targetBubble = NULL;
clickOnBubble(mousePos, bubbles, targetBubble);
Why it is not working?
Because you are passing a copy of pointer. To change the pointer you need something like this:
void foo(int **ptr) //pointer to pointer
{
*ptr = new int[10]; //just for example, use RAII in a real world
}
or
void bar(int *& ptr) //reference to pointer (a bit confusing look)
{
ptr = new int[10];
}
You are passing the pointer by value.
Pass a reference to the pointer if you want it updated.
bool clickOnBubble(sf::Vector2i& mousePos, std::vector<Bubble *> bubbles, Bubble *& t)
if you write
int b = 0;
foo(b);
int foo(int a)
{
a = 1;
}
you do not change 'b' because a is a copy of b
if you want to change b you would need to pass the address of b
int b = 0;
foo(&b);
int foo(int *a)
{
*a = 1;
}
same goes for pointers:
int* b = 0;
foo(b);
int foo(int* a)
{
a = malloc(10); // here you are just changing
// what the copy of b is pointing to,
// not what b is pointing to
}
so to change where b points to pass the address:
int* b = 0;
foo(&b);
int foo(int** a)
{
*a = 1; // here you changing what b is pointing to
}
hth
You cannot change the pointer unless you pass it by (non const) reference or as a double pointer. Passing by value makes a copy of the object and any changes to the object are made to the copy, not the object. You can change the object that the pointer points to, but not the pointer itself if you pass by value.
Have a read of this question to help understand the differences in more detail When to pass by reference and when to pass by pointer in C++?

Reason to Pass a Pointer by Reference in C++?

Under which circumstances would you want to use code of this nature in c++?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
You would want to pass a pointer by reference if you have a need to modify the pointer rather than the object that the pointer is pointing to.
This is similar to why double pointers are used; using a reference to a pointer is slightly safer than using pointers.
50% of C++ programmers like to set their pointers to null after a delete:
template<typename T>
void moronic_delete(T*& p)
{
delete p;
p = nullptr;
}
Without the reference, you would only be changing a local copy of the pointer, not affecting the caller.
David's answer is correct, but if it's still a little abstract, here are two examples:
You might want to zero all freed pointers to catch memory problems earlier. C-style you'd do:
void freeAndZero(void** ptr)
{
free(*ptr);
*ptr = 0;
}
void* ptr = malloc(...);
...
freeAndZero(&ptr);
In C++ to do the same, you might do:
template<class T> void freeAndZero(T* &ptr)
{
delete ptr;
ptr = 0;
}
int* ptr = new int;
...
freeAndZero(ptr);
When dealing with linked-lists - often simply represented as pointers to a next node:
struct Node
{
value_t value;
Node* next;
};
In this case, when you insert to the empty list you necessarily must change the incoming pointer because the result is not the NULL pointer anymore. This is a case where you modify an external pointer from a function, so it would have a reference to pointer in its signature:
void insert(Node* &list)
{
...
if(!list) list = new Node(...);
...
}
There's an example in this question.
I have had to use code like this to provide functions to allocate memory to a pointer passed in and return its size because my company "object" to me using the STL
int iSizeOfArray(int* &piArray) {
piArray = new int[iNumberOfElements];
...
return iNumberOfElements;
}
It is not nice, but the pointer must be passed by reference (or use double pointer). If not, memory is allocated to a local copy of the pointer if it is passed by value which results in a memory leak.
One example is when you write a parser function and pass it a source pointer to read from, if the function is supposed to push that pointer forward behind the last character which has been correctly recognized by the parser. Using a reference to a pointer makes it clear then that the function will move the original pointer to update its position.
In general, you use references to pointers if you want to pass a pointer to a function and let it move that original pointer to some other position instead of just moving a copy of it without affecting the original.
Another situation when you may need this is if you have stl collection of pointers and want to change
them using stl algorithm. Example of for_each in c++98.
struct Storage {
typedef std::list<Object*> ObjectList;
ObjectList objects;
void change() {
typedef void (*ChangeFunctionType)(Object*&);
std::for_each<ObjectList::iterator, ChangeFunctionType>
(objects.begin(), objects.end(), &Storage::changeObject);
}
static void changeObject(Object*& item) {
delete item;
item = 0;
if (someCondition) item = new Object();
}
};
Otherwise, if you use changeObject(Object* item) signature you have copy of pointer, not original one.
Refer the code below:
When we pass x as Node *x, a new variable is created with the same address passed on by the caller function.
If you modify the value pointed by the pointer, that change will be reflected in the caller function variable.
But if we change the value of the pointer itself it will not be reflected in the caller function because callee function has the copy of the passed pointer not the original pointer itself.
void increment(int *x) {
(*x)++;
x++;
cout << x << endl; // prints 0x7ffe9f8e1900
}
int main() {
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints 11
cout << x << endl; // prints 0x7ffe9f8e18fc
return 0;
}
Now, check the below code:
When we pass x as Node *&x, we pass a reference of the original variable present in the caller function meaning these two variable (caller and callee root) are same, their name may differ.
if we modify the value pointer by the pointer, that change will be reflected in the caller function variable.
Now if we change the value of the pointer itself it will also be reflected in the caller function variable.
void increment(int* &x)
{
(*x) ++;
cout << *x << endl; // prints 11
x++;
cout << x << endl; // prints 0x7fffb93eba70
}
int main()
{
int a = 10;
int *x = &a;
increment(x);
cout << *x << endl; // prints garbage
cout << x << endl; // prints 0x7fffb93eba70
return 0;
}

Is it passing by pointer?

void func(char* buf) { buf++;}
Should I call it passing by pointer or just passing by value(with the value being pointer type)? Would the original pointer passed in be altered in this case?
This is passing by value.
void func( char * b )
{
b = new char[4];
}
int main()
{
char* buf = 0;
func( buf );
delete buf;
return 0;
}
buf will still be 0 after the call to func and the newed memory will leak.
When you pass a pointer by value you can alter what the pointer points to not the pointer itself.
The right way to do the above stuff would be
ALTERNATIVE 1
void func( char *& b )
{
b = new char[4];
}
int main()
{
char* buf = 0;
func( buf );
delete buf;
return 0;
}
Notice the pointer is passed by reference and not value.
ALTERNATIVE 2
Another alternative is to pass a pointer to a pointer like
void func( char ** b )
{
*b = new char[4];
}
int main()
{
char* buf = 0;
func( &buf );
delete buf;
return 0;
}
Please note I am not in any way advocating the use of naked pointers and manual memory management like above but merely illustrating passing pointer. The C++ way would be to use a std::string or std::vector<char> instead.
The pointer will not be altered. Pass by pointer means pass an address. If you want the pointer altered, you have to pass a double pointer a deference it once.
foo( char **b)
{
*b = NULL;
}
The pointer itself is being passed by value (the memory being pointed at is being passed by pointer). Changing the parameter inside the function will not affect the pointer that was passed in.
To implement reference semantics via "passing a pointer", two things must happen: The caller must take the "address-of" the thing to be passed, and the callee must dereference a pointer.
Parts of this can be obscured by the use of arrays, which decay to a pointer to the first element - in that sense, the array content is always "passed by reference". You can use an "array-of-one" to obscure the dereferencing, though.
This is the straight-forward apporoach:
void increment_me(int * n) { ++*n; } // note the dereference
int main() { int n; increment_me(&n); } // note the address-of
Here's the same in disguise:
void increment_me(int n[]) { ++n[0]; } // no visible *
int main() { int n[1]; increment_me(n); } // or &