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;
}
Related
Something like this:
void f()
{
int* p = NULL;
if (condition)
{
int a = 3;
p = &a;
}
// use p...
}
And if no, in what circumstances would this go wrong?
Is it safe?
No, it is not safe as it is considered undefined behavior by the standard. Accessing the memory of something after its scope has expired means that it can equal anything.
In what circumstances would this go wrong?
Let's take a look at your current example:
void f()
{
int* p = NULL;
if (condition)
{
int a = 3;
p = &a;
}
int x = 5;
// p may now point to x,
// or some other variable on the stack,
// or it might not do either and may point to invalid memory.
// it depends on what your compiler decides to do.
// this is what is meant by "undefined behavior."
}
On an unrelated note, if p was never assigned, p still points to NULL and accessing it will throw an exception.
So, what's the alternative? You've got more than one option, but here is the simplest in my opinion that still maintains the same usage:
void f()
{
int* p = NULL;
if (condition)
{
p = new int{3};
int& a = *p;
// use a
}
// use p as you normally would, be sure to check for nullptr
// you must delete p as well.
}
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++?
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++?
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++?
What is the difference between the two copy functions below? I do not seem to see a difference between them. Specifically the void*& vs the void*.
So what is the difference between T*& and T*? When would I use one over the other? Also, if I made them accept const parameters, what would happen? What would the difference be?
#include <iostream>
void Copy(void* Source, void* Destination, int Size)
{
//memcpy(Destination, Source, Size);
char* S = static_cast<char*>(Source);
char* D = static_cast<char*>(Destination);
*D = *S;
}
void Copy2(void* &Source, void* &Destination, int Size)
{
char* S = static_cast<char*>(Source);
char* D = static_cast<char*>(Destination);
*D = *S;
}
int main()
{
int A = 2;
int B = 5;
int C = 7;
void* pA = &A;
void* pB = &B;
void* pC = &C;
Copy(pA, pB, 1);
Copy2(pA, pC, 1);
std::cout<< B <<std::endl;
std::cout<< C <<std::endl;
}
Both of the above print "2". Both are the same no?
One is a pointer, the other is a reference to a pointer.
Google both and pick up a C++ basics book.
Think of passing by pointer as passing a memory address by value (ie, a copy). In the receiving function, you have a copy of the memory address and you can change where that memory address pointer points to, and what that destination memory contents looks like. When you return from that function, the destination memory is still changed, but the original pointer is unchanged.
In contrast, a reference to a pointer allows you to change where that memory points to after you return from the function. Otherwise it is the same.
A common usage is a funciton which allocates memory such as:
SomeClass *someClass = null;
PopulateSomeClass(someClass);
...
void PopulateSomeClass(SomeCLass* &someCLass)
{
someClass = new SomeClass;
}
But really, google this for more detail - this is a more basic C++ concept.
For instance, a reference is typically implemented as a const * under the covers in the compiler. So it is a const pointer to pointer.