How to pass a pointer variable as a reference parameter? - c++

When you have a function like this, the formal parameter is a reference, it becomes another name for the actual argument, so that when we modify the formal parameter inside the function, the original variable outside the function is changed.
void add_five(int& a)
{
a += 5;
}
int main()
{
int number = 3;
add_five(number);
std::cout << number << std::endl; // prints 8
return 0;
}
I have some code which works on a linked lists. And I am passing two Node*s into the function.
void LinkedList::move_five_nodes(Node* ptr1, Node* ptr2) { ... }
...
void LinkedList::anotherFunction()
{
Node* leader;
Node* trailer;
...
move_five_nodes(leader, trailer);
...
}
I think that the rvalues memory addreses inside the leader and trailer pointer variables will be assigned into the Node* lvalues ptr1 and ptr2.
Node* ptr1 = leader;
Node* ptr2 = trailer;
The issue is that ptr1 and ptr2 are independent local variables inside the function. Initially, they point to the same place as the actual argument pointers. However, my function moves some nodes, and at the end of the function, the values of ptr1 and ptr2 are changed. I want these changes to also be in the original variables leader and trailer, just like references. So even when ptr1 and ptr2 expire, leader and trailer should go into their positions.
How would I do this? Maybe type cast the pointers into int&? Or maybe use pointers to pointers? I want to pass a pointer by reference, but I'm not sure how to do that.

I want to pass a pointer by reference, but I'm not sure how to do that.
For this, consider the following snippet
#include <iostream>
void test(int*& t)
{
t = nullptr;
}
int main()
{
int* i = new int(4);
test(i);
if (i == nullptr)
std::cout << "I was passed by reference" << std::endl;
}
in which is is passed by reference to test, where it is set to nullptr and the program prints: I was passed by reference.
I think this example should make clear how to pass a pointer by reference to a function.
So in your case the function signiture must change to
void LinkedList::move_five_nodes(Node*& ptr1, Node*& ptr2) { ... }

#include <iostream>
void test(int& ref);
int main()
{
int* pointer = new int(10);
std::cout << "before" << *pointer << std::endl ;
test(*pointer);
std::cout << "after" << *pointer << std::endl;
delete pointer;
}
void test(int& ref)
{
ref = 20;
}

Related

function to not be able to change both the value and the address of the pointer

How should be the signature of a funtion
in order to not be able able to change
both the value and the address of the passed pointer?
void testP(int*& k)
{
std::cout << "testP addr:" << k << std::endl;
}
int main()
{
int* p = new int(5);
testP(p);
delete p;
return 0;
}
How should be the signature of a funtion in order to not be able able to change both the value and the address of the passed pointer?
You need to make the parameter to be a reference to a const pointer to a const int as shown below:
//---------vvvvv-----vvvvv----------->added const
void testP(const int*const& k);
{
//*k = 4; //NOT ALLOWED
// k = nullptr ; //NOT ALLOWED
}
Note that the parameter k in the above declaration will be the same if you change the parameter declaration to int const* const&.

Pointer to class field as lambda argument

Why if we pass a class field pointer int* value in a lambda, then doesn't change value?
struct A {
A() {
auto f = [](int* value) {
value = new int(0);
};
f(value);
}
int* value = new int(42);
};
int main()
{
A obj{};
std::cout << *(obj.value) << std::endl;
}
Changes made to a function parameter are not visible to the caller, unless you take it by reference.
In your case, you would simply need to do
auto f = [](int* &value) {
value = new int(0);
};
Now changes to the parameter value are reflected in the member value.
Note that in your example, (without the reference), the compiler would warn that you are setting value but not using it.
Also, this might solve the specific question, but you are still leaking memory here.
your code isn't compilable - you cannot assign int* to int here: value = int(0);.
I have tried your code with fixed mentioned error:
struct A {
A() {
auto f = [](int* value) {
*value = int(0); // here value is being changed as expected
};
f(value);
}
int* value = new int(42);
};
int main()
{
A obj{};
std::cout << *(obj.value) << std::endl;
}
Everything works fine - passed value pointer to the f lambda is being changed from 42 to 0 value after constructor of struct is called.

C++ Deleting pointer with function

I have one question. Is it possible to delete a pointer with function? This is my example:
void deletePointer(auto* pointer)
{
delete pointer;
pointer = nullptr;
}
int main()
{
int value = 5;
int* value_ptr = &value;
//Some code
deletePointer(value_ptr);
return 0;
}
And it doesn't work. I also tried adding "inline" keyword to function and with lambda.
auto deletePointer = [&](auto* pointer) -> void
{
delete pointer;
pointer = nullptr;
}
I think it only deletes pointer inside of function, lambda. Is it possible to make function that will delete pointer, which is passing to function?
Solution.
I got to know that delete can be used only when object is creating using new. So I changed code a bit.
#include <iostream>
void deletePointer(auto*& pointer)
{
delete pointer;
pointer = nullptr;
}
int main()
{
int* ptr = new int(5);
deletePointer(ptr);
if (ptr == nullptr) std::cout << "Succeed";
else std::cout << "Failed";
return 0;
}
And given output from code is: Succeed.
So now everything works.
Thanks for help :)

Why this code showing an error lvalue required in line 1? How to resolve it?

#include<iostream>
using namespace std;
class Test
{
private:
int x;
public:
Test(int x = 0) { this->x = x; }
void change(Test *t)
{
this = t; //line 1
}
void print() { cout << "x = " << x << endl; }
};
int main()
{
Test obj(5);
Test *ptr = new Test (10);
obj.change(ptr);
obj.print();
return 0;
}
since we know that this pointer hold the reference of calling object. In line 1 i am trying to change the reference of calling object but it shows an error "lvalue required". Can someone explain this??
You cannot assign a pointer to this pointer, because it's a prvalue.
this pointer is a constant pointer that holds the memory address of the current object.
As a result, this is of type const Test* in your case, so it cannot be assigned to. Doing so (if it was allowed) would effectively allow an object to change its own address in memory, as #Peter mentioned.
Note: const Test* is a pointer to a constant object. The object it points to is constant, not the pointer itself.
PS: this->x = t->x; is probably what you meant to say.
Here you are assigning a pointer(here t) to "this" pointer for a particular object.
"this" pointer is const. pointer that holds the memory address of the current object. You simply can't change the this pointer for an object, since doing this you will practically be changing the location of the object in the memory keeping the name same.
Reference - ‘this’ pointer in C++
#include <iostream>
using namespace std;
class Test
{
private:
int x;
public:
Test(int x=0)
{
this->x = x;
}
void change(Test *t)
{
t->x; //t is a pointer. so make it point to x
}
void print() { cout << "x = " << x << endl; }
};
int main()
{
Test obj(5);
Test obj1(10); //create a new object
Test *ptr = &obj1;//make the pointer point to obj1
obj.change(ptr); //use change() to point to argument of obj1
obj.print(); //print the value of obj now
return 0;
}

Moving a pointer through array - passing by reference or incrementation?

I have absolutely no clue, what the difference is between the two following examples:
void function(int *p) {
p++;
}
int main() {
int values[] = {1,2,3};
int *p = values;
function(p);
cout << *p;
return 0;
}
This one returns "1".
Whereas a slight modification yields "2" (which is the wanted result):
int main() {
int values[] = {1,2,3};
int *p = values;
p++;
cout << *p;
return 0;
}
Where lies the problem? Is it due to passing by reference or incrementing?
The issue here is
void function(int *p) {
p++;
}
Is using pass by value - not pass by reference. Since the pointer is passed by value any change you make to the pointer itself is not reflected in the call site. If you need to modify where the pointer points then you need to pass it by reference like
void function(int*& p) {
p++;
}
Now when you increment it will point to the second element like it does in your second example.
In this example
void function(int *p) {
p++;
}
int main() {
int values[] = {1,2,3};
int *p = values;
function(p);
cout << *p;
return 0;
}
You are passing a pointer by value, which means you simply pass a copy of the address the pointer is pointing at. You then proceed to increment the function's local copy of that pointer and then exit the function. This has no effect on the original pointer as you incremented a local copy.
In this example, however
int main() {
int values[] = {1,2,3};
int *p = values;
p++;
cout << *p;
return 0;
}
You directly increment your pointer, which means it is now pointing at the next element in the array.
In the first case the value of address is passed by value.
function(p) ==> void function(int *p){}
The 'p' on right side a local variable. So any modification to the pointer will be visible only inside function.