Changing the address of a pointer after construction - c++

I've tried to create a minimal example of my problem. I'm trying to check if the address of an void pointer is NULL or not. The address should be overgiven by constructing the class, and should be const. I wrote the class below.
MyPointer.h:
public:
MyPointer(const void* activeApp) : m_activeApp(activeApp){
std::cout <<"adresse on construction: " << m_activeApp << std::endl;
};
MyPointer.cpp:
void printAdress();
private:
const void* m_activeApp;
};
The Methode "printAdress" should be able to print the correct address of the given pointer.
int main(void){
void* p_activeApp = nullptr;
std::cout << p_activeApp << std::endl;
MyPointer myPointer(p_activeApp);
std::cout << "Should be 0: " ;
myPointer.printAddress();
p_activeApp = new(bool);
std::cout << "Should be anything: ";
myPointer.printAddress();
}
void MyPointer::printAddress() {
std::cout << this->m_activeApp << std::endl;
};
Of course it doesn't work, because the m_activeApp still points to NULL, but how can I change this?

If you want to change what myPointer.m_activeApp points to, you have to set the pointer to a different value, simple as that. This pointer and p_activeApp are two distinct, independent pointers. Changing one does not change the other.
What you can do is to make one pointer a reference to the other pointer instead. Then, changing one would also change the other. This will work, though be warned, it won't be good programming style.

Pointers are integers (representing a memory location), so imagine void* to be a number. You set p_activeApp to 0, then you construct a MyPointer, and its internal pointer is set to 0.
Then you change the first number by using the new operator, p_activeApp now gets a value (to that new memory address), but there's no reason for m_activeApp to also change. It still points at 0, no matter what p_activeApp changes to.

I fixed it like this:
public:
MyPointer(void** activeApp) : m_pp_activeApp(activeApp) {
std::cout <<"address on construction: " << *m_pp_activeApp << std::endl;
};
void printAddress();
private:
void** m_pp_activeApp;
};
int main(void){
void* p_activeApp = nullptr;
void** pp_activeApp = &p_activeApp;
MyPointer myPointer(pp_activeApp);
std::cout << "Should be 0: " ;
myPointer.printAddress();
p_activeApp = new(bool);
std::cout << "Should be anything: ";
myPointer.printAddress();
}
void MyPointer::printAddress() {
std::cout << *m_pp_activeApp << std::endl;
};

Related

Changing the address of a pointer to edit its value

recently we were trying to use pointer to void, by passing a copy of its address to an instance of a class, in order for the instance to allocate it to the same memory space as an OpenCV Mat it contains, and that is contained in a stack of memory shared by the GPU and CPU to compute it with OpenCV+CUDA.
However while doing that we ran into an issue we didn't quite understand. When passing the address of the pointer to the object, we tried to edit that address so that the pointer was hosted on another space. And while that worked once that copy ran out of scope the value of that pointer returned to being what it was (I'll add a code snip since its confusing to even explain it). However if we accessed the content of the pointer's address that we passed to the function, and edit that, the original pointer is edited.
My hypothesis is that when we passed the pointer's address to the function a copy of the value of that memory address is made, and if that pointer to pointer is edited, the content of it is left undisturbed, while on the other function we accessed the content and directly edited it, hence the copy is left undisturbed and runs out of scope, while the content is edited correctly.
Here is a snip of the code where I try both things:
// Example program
#include <iostream>
#include <string>
void change_value(int **p, int *addr)
{
*p = addr;
}
void change_direction(int **p, int *addr)
{
std::cout << "p value: " << p << std::endl;
std::cout << "p contains: " << *p << std::endl;
std::cout << "p contains contains: " << **p << std::endl;
p = &addr;
std::cout << "p value: " << p << std::endl;
std::cout << "p contains: " << *p << std::endl;
std::cout << "p contains contains: " << **p << std::endl;
}
int main()
{
int a = 1, b = 2, c = 3;
int *ptr = &a;
std::cout << "ptr direction: " << &ptr << std::endl;
std::cout << "ptr value: " << ptr << std::endl;
std::cout << "ptr contains: " << *ptr << std::endl;
std::cout << std::endl;
change_value(&ptr, &b);
std::cout << "change_value" << std::endl;
std::cout << "ptr direction: " << &ptr << std::endl;
std::cout << "ptr value: " << ptr << std::endl;
std::cout << "ptr contains: " << *ptr << std::endl;
std::cout << std::endl;
change_direction(&ptr, &c);
std::cout << std::endl;
std::cout << "change_direction" << std::endl;
std::cout << "ptr direction: " << &ptr << std::endl;
std::cout << "ptr value: " << ptr << std::endl;
std::cout << "ptr contains: " << *ptr << std::endl;
}
This is the output we got. We can see that while ptr is edited on change_value function, since we access to the content of p and edit it, it is not changed on change_direction, since the moment we edit p's address it stops pointing to ptr.
ptr direction: 0x710a27e3fe18
ptr value: 0x710a27e3fe0c
ptr contains: 1
change_value
ptr direction: 0x710a27e3fe18
ptr value: 0x710a27e3fe10
ptr contains: 2
p value: 0x710a27e3fe18
p contains: 0x710a27e3fe10
p contains contains: 2
p value: 0x710a27e3fdd8
p contains: 0x710a27e3fe14
p contains contains: 3
change_direction
ptr direction: 0x710a27e3fe18
ptr value: 0x710a27e3fe10
ptr contains: 2
If anyone could offer a better explanation of what happened I'd be most grateful.
Cheers.
Not sure if I understand the question, but if this:
void change_direction(int **p, int *addr)
{
// ...
p = &addr;
// ...
}
Is supposed to modify the parameter passed to the function, then it isnt correct.
Parameters are passed by value unless you pass them by reference. Passing references is recommended, but if you like you can use pointers. However, then you need to modify what the pointer points to, not the pointer. In the function above p is local to the function. Modifying the value of p has no effect outside the function.
You probably want:
void change_direction(int **p, int *addr)
{
// ...
*p = addr;
// ...
}
Or rather
void change_direction(int *&p, int *addr)
{
// ...
p = addr; // p is a reference, hence no dereference needed
// ...
}
Actually you should prefer int*& here, because a nullptr is not a valid paramter (and thats about the only reason you would use a pointer rather than a reference).
#463035818_is_not_a_number offered a good answer that works well.
But there might be value in fully understanding what your original code is doing.
Beggining from the start:
int a = 1, b = 2, c = 3;
int *ptr = &a;
This initializes three pieces of memory in stack memory containing the int values you gave (a,b,c) and one more piece of memory for your ptr variable that holds the address of a.
You then print out the address and the values of ptr, which obviously doesn't change any of the values.
Next is the call to change_value(int **p, int *addr) which executes.
*p = addr;
The parameter p in this case holds an address to an address to an int somewhere in memory, so *p is the address pointed to by p.
Setting that to addr changes the address p points to.
So in your specific code:
change_value(&ptr,&b);
Sets the value of ptr to be the address of b.
Then next is the change_direction(int **p, int* addr) call (which probably should be named change_address), which executes (ignoring the printing):
p = &addr;
This sets the parameter p to be the address of addr.
But since in C/C++ all functions are called by value (in C there arent even any references, in C++ you have to specify it as #463035818_is_not_a_number mentioned), this doesnt do anything to the original values, that the function has been called with.
So the call:
change_direction(&ptr,&c)
Does not actually change what is held in ptr. At the beginning of the call to the function, the address of ptr (so &ptr) gets copied into a piece of stack-memory, which is then used in the function and freed after the function exits.
I hope this clears things up, pointers can be hard to wrap your head around sometimes.
Cheers.

Questions about the ownership transfer of unique_ptr

For the following code:
#include <memory>
#include <iostream>
#include <vector>
using namespace std;
struct pm
{
pm() : a(make_unique<vector<int>>(1, 10)){};
unique_ptr<vector<int>> a;
};
struct parms
{
parms() : a(make_unique<pm>()){};
unique_ptr<pm> a;
};
class test
{
public:
test() : p(make_unique<parms>()) {}
unique_ptr<const parms> getParms()
{
return move(p);
}
void setParms(int b)
{
p->a->a->push_back(b);
}
void pp()
{
cout << p->a->a->at(0) << "\n";
}
private:
unique_ptr<parms> p;
};
int main()
{
auto t = make_unique<test>();
t->pp();
cout << t->getParms()->a->a->at(0) << "\n";
cout << (t->getParms()==nullptr) << "\n"; ;
}
t->getParms() is a nullptr after we "cout << t->getParms()->a->a->at(0) << "\n";".
If we do the same thing for the ptr,
int main()
{
auto t = make_unique<test>();
t->setParms(5);
t->pp();
auto ptr = t->getParms();
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
}
ptr is not a nullptr.
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not? Is it because of the life scope of unique_ptr? Or the temporary rvalue? What's the reason behind this behavior?
Your method getParams() transfers ownership to the caller.
unique_ptr<const parms> getParms()
{
return move(p);
}
Member is moved to the return value and now the caller owns the pointee. You are not storing the returned value here:
cout << t->getParms()->a->a->at(0) << "\n";
Though, even if you did, t does not own the param anymore, hence when you ask t again:
cout << (t->getParms()==nullptr) << "\n"; ;
It doesnt know about the param anymore.
In the second example you transfer ownership from t to ptr:
auto ptr = t->getParms();
Now ptr owns the param. And you can inspect the pointer or the value as often as you like:
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
There is no transfer of ownership in those two lines.
What's the reason behind this behavior?
The reason, as stated above, is that getParams() transfers ownership to the caller. Thats rather uncommon for a getter method. Perhaps "stealer-method" would be a better name ;). If you don't want to give up ownership (and you are certain that the pointer is a valid one) you can simply return a reference:
const parms& getParms() const { return *p; }
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not?
t->getParms() transfers the ownership to the caller. This sets t->p to null. Since t->p no longer owns a pointer, there is nothing to transfer when you call t->getParms() a second time.
You never transferred ownership from ptr, so it hasn't been set to null.

Pointer Syntax Within Condition

After a pointer is initialized, do you have to use the * dereference operator to call the pointer in a condition?
Example:
int main()
{
int var = 10;
int *ptr = &var;
if(ptr) // does this need to be if(*ptr) ???
{.......}
}
And can I have a short explanation as to why?
Thank you.
if (ptr)
check if the pointer is not Null but
if (*ptr)
check if the value it points to is not zero (in this example is 10)
So for checking the value you shoud add *.
It depends on what you want to do.
if(ptr) checks if the pointer value is nullptr or not. Note that this is shorthand for if(ptr != nullptr).
if(*ptr) checks if what the pointer points to is nullptr (or 0) - and in that case, since you dereference (follow) the pointer to answer the question, the pointer itself had better not be nullptr in that case.
First of all, a pointer is only a variable. However, there are different contexts in which you can use it.
As any other variable you can access the pointers content (which is the adress of the underlying memory) as follows:
int i = 1;
int * p = &i;
std::cout << p << std::endl
this would output the adress of i since this is what is stored in p
If you however want to access the content of the underlying memory (the value of i), you need to dereference the pointer first by using the * operator:
std::cout << *p << std::endl;
This would print the value of iso 1.
of course you can also access the pointer's adress (since the adress of i is a numeric value as well and needs to be stored somewhere too):
std::cout << &p << std::endl;
That would output the adress of p so the adress where the adress of i is stored :)
As a little example try to run this code:
#include <iostream>
int main() {
int i = 1;
int * p = &i;
std::cout << "Value of i(i): " << i << std::endl
<< "Adress of i(&i): " << &i << std::endl
<< "Value of p(p): " << p << std::endl
<< "Dereferenced p(*p): " << *p << std::endl
<< "Adress of p(&p): " << &p << std::endl
<< "Dereferenced adress of p(*(&p)): " << *(&p) << std::endl;
}

New pointer in class method must be casted into a reference

I have two classes, let's call them A and B
class A:
{
public:
//Some functions
A *getNewA() const;
private:
//some attributes
}
class B:
{
public:
//Some functions
private:
A &reftoA;
}
In the main code, I must generate a new A thanks to the A::getNewA() method. And this must go to B::reftoA, as written in class B.
Here is the A::getNewA() method :
A *A::getNewA()
{
A *newA = new A;
return newA;
}
OK. So now I call getNewA and want to store the results in reftoA, which is a reference to A. In a B function (which take a reference to A as parameter)
B::foo(A &paramA)
{
reftoA = *(paramA.getNewA());
}
I thought this should have been working, but it won't.
Because when dereferencing, reftoA will always take the this object and not the new allocated object.
Let's be clearer and let's modify the functions to output the results
A * A::getNewA()
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return A;
}
void B::foo(A &paramA)
{
reftoA = *(paramA.getNewA());
std::cout << "new generated pointer " << &reftoA << std::endl;
}
Here is one of the output :
New pointer : 004FFAEC
this pointer: 0069D888
New generated pointer : 0069D888 //Expected : 004FFAEC
I can't get this "new generated pointer" to be the same than the new pointer the A::getNewA() returns after having allocated the memory. Of course, I guess there is some point with dereferencing the pointer to store it in a reference.
I know reference are used with existing object. Maybe the new object A::getNewA() should allocate memory for won't work as I expected.
I could use pointer instead reference in B::foo(), I know, but I can't
I think I am misunderstanding something about refrence and pointer, but I don't know what.
Any help greatly appreciated
The problem is that you can not reassign a reference. You can change only the value of the referenced object.
So you have to initialize the reference in the initializer list of the constructor of the class B.
Take into account that there is a typo in your code snippet
A*A::getNewA()
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return A;
^^^^^^^^^
}
I think you mean
A*A::getNewA() const
^^^^^
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return newA;
^^^^^^^^^^^
}
Always try to provide a verifiable complete example.
Here is a demonstrative program
#include <iostream>
class A
{
public :
//Some functions
A* getNewA() const
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return newA;
}
private :
//some attributes
};
class B
{
public :
B( const A& a ) : reftoA( *a.getNewA() )
{
std::cout << "&reftoA " << &reftoA << std::endl;
}
private :
A& reftoA;
};
int main()
{
A a;
B b( a );
return 0;
}
Its output is
New pointer 0x2b392afbec20
this pointer0x7ffd287ad0af
&reftoA 0x2b392afbec20
As you can see the values of the New pointer and &reftoA are equal each other.
To make it more clear consider a very simple example
#include <iostream>
int main()
{
int x = 10;
int y = 20;
int &r = x;
r = y;
std::cout << "x = " << x << std::endl;
std::cout << "y = " << y << std::endl;
std::cout << "r = " << r << std::endl;
std::cout << std::endl;
std::cout << "&x = " << &x << std::endl;
std::cout << "&y = " << &y << std::endl;
std::cout << "&r = " << &r << std::endl;
return 0;
}
The program output is
x = 20
y = 20
r = 20
&x = 0x7ffd88ad47a8
&y = 0x7ffd88ad47ac
&r = 0x7ffd88ad47a8
This statement
r = y;
did not force the reference to refer the object y. It just reassigned the value of the referenced object x.
References have to be initialized when they are created.
Yes, you are misunderstanding something.
getNewA() is returning a pointer. it's not a smart pointer, you want to look into those and that's all I'll say on the matter.
on returning a pointer, you must keep a reference to this pointer else you will be unable to delete it and you'll get a memory leak. Thus you MUST have somewhere A* a = A::getNewA() and then later, when you no longer need it delete a;
Where you need to pass a reference to A, you can do foo(*a) which will dereference the pointer and pass a reference to the object it's pointing to.
But in summary, for all new code, smart pointers; there's no excuse to not use them.
Side note: Your code example had a few other issues; such as getNewA wasn't static; I'm going to take the code as a working example of your understanding, and not a working example.
Edit: On re-reading your example, the getNewA is intentionally non-static. I think this question is actually an XY problem (ie you're asking a question you've forced yourself into but isn't your actual problem); but I hope this addresses your misunderstanding of pointers and references.
You are not returning the pointer in the getNewA-Method
A* A::getNewA()
{
A *newA = new A;
return A; // you are returning A and not newA
}
And if you want to reassign the reference to a you can use a std::reference_wrapper
class B :
{
public :
void foo(A& paramA) {
reftoA = *(paramA.getNewA());
}
private :
std::reference_wrapper<A> reftoA;
}

Passing default string pointer to function

there is a prototype of a function in my fuu.h. I want to pass default values if there
void MyFunction(
int iError = 0,
std::string * MyProblemString = ""
);
// Some attemts:
void MyFunction(
int iError = 0,
std::string * MyProblemString = std::string{""}; // does not work to, complains about missing '*'
);
void MyFunction(
int iError = 0,
std::string * MyProblemString = &std::string{""}; // does not work to, refering address to temporary value
);
void MyFunction(
int iError = 0,
std::string * MyProblemString = *std::string{""}; // does not work to, overloaded operator not known
);
void MyFunction(
int iError = 0,
std::string * MyProblemString = ""; // could not convert ‘""’ from ‘const char [1]’ to ‘std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}’
);
in my c-file is written:
void MyFunction(
int iError,
std::string * MyProblemString,)
{
// do some stuff
}
With the int it's working fine. How can I make the same thing with the string?
There are some examples with other constructions, but passing a pointer does not work.
const reference default-value
thx
I don't think you understand what pointers do. I'll try to help.
Pointers
int number; // An int
int * pointer; // A valid pointer to an int
int* pointer; // Also a valid pointer to an int
int *pointer; // Also a valid pointer to an int
"number" is a named variable of type integer with a chunk of memory big enough to store an int assigned to it. This chunk of memory is given a memory address.
Pointers are basically like an int, except the number they store is the memory address of another variable - in your case, "number".
The & operator will give you the memory address of the variable you use it on.
&number
This will give you the memory address of your int "number".
pointer = &number; // Pointer now contains the memory address of "number"
Now if you try to use pointer like an int, it will give you the address of "number", not its contents. To access the contents of whatever your pointer is pointing at, prefix it with *.
void main()
{
int number = 56;
int* pointer = number; // INVALID: Pointer now pointing at memory location "56"
int* pointer = &number; // Valid: Pointer now pointing at memory location of number
int* pointer; // DANGEROUS, DO NOT LEAVE HANGING POINTERS -- leads to memory access violations
int *pointer = nullptr; // Safely initialise unused pointer
int size = 32;
pointer = new int; // Allocates a block of memory the size of 1 int. Pointer now points at this memory
pointer = new int[size]; // Allocates an array of 32 ints to pointer. Pointer now points to this block of memory
pointer = new int[8]; // Allocates another array to pointer. Pointer now points at the new array, old array has nothing pointing at it and is lost in memory!
// This is a memory leak. AVOID MEMORY LEAKS AT ALL COSTS, they can produce some of the hardest-to-find bugs you'll come across
delete pointer; // Deletes chunk of memory the size of 1 int at the memory pointer is pointing at
delete[] pointer; // Deletes array of memory following the location pointer is pointing at
// IMPORTANT: ALWAYS use delete with new, delete[] with new[]
// IMPORTANT: NEVER use new or new[] without its delete counterpart, or you will encounter memory leaks
// USEFUL:
if (pointer != nullptr)
{
// Do stuff
}
// Doing this will ensure you don't act upon memory you aren't supposed to mess with
// Print these to console to gain a better understanding.
std::cout << number << std::endl;
std::cout << &number << std::endl;
std::cout << pointer << std::endl;
std::cout << *pointer << std::endl;
system("pause");
}
Pay attention to the output:
Output on my machine (the address will vary when you run it):
56 // number
0035F7E0 // &number
0035F7E0 // pointer
56 // *pointer
Note that "&number" and "pointer" print the same thing
You can use & and * to assign pointers to anything, including pointers to other pointers to other pointers to other pointers to whatever the hell you want. It gets messier the deeper you go with things like that, but the point is (pun unintended) pointers are one of the most versatile and handy (but also dangerous -- MEMORY LEAKS, ACCESS VIOLATIONS, AHHH) things to use in C++.
Hope this helped, post a reply to this answer if you don't understand or if this didn't help you understand your problem.
The problem you are having is because you can't give a default value to a pointer without dealing with the memory the pointer is supposed to point to. If you use a std::string instead of a pointer to std::string then you can use the simple string literal syntax as in MyFunction().
If you need to pass a pointer to a string, because you are planning to manipulate the string or for some other purpose, you can give the string the default value of NULL. Since NULL does not point to any memory, this is a perfectly sane default for a pointer. Then you can check for this value, and allocate a new std::string in that special case. That is what I am doing in MyFunction2.
HOWEVER if you allocate memory, you must free that memory somewhere. In my example, I am freeing the memory inside of MyFunction2 only if I also created it. If the value was supplied, I am not freeing the value, but rather leaving that up to the calling function. How you manage memory will depend on your use case, but don't forget about this crucial step.
#import <iostream>
void MyFunction(
int iError = 1,
std::string MyProblemString = std::string(""))
{
std::cout << "\tiError = " << iError << ", and MyProblemString = " << MyProblemString << std::endl;
}
void MyFunction2(
int iError = 1,
std::string * MyProblemString = NULL)
{
bool shouldFree = MyProblemString == NULL;
if (shouldFree){
MyProblemString = new std::string("");
}
std::cout << "\tiError = " << iError << ", and MyProblemString = " << *MyProblemString << std::endl;
if(shouldFree){
delete MyProblemString;
}
}
int main(){
std::string * test = new std::string("test");
std::cout << "Testing with MyFunction:" << std::endl;
std::cout << "\tTest default arguments:" << std::endl;
MyFunction();
std::cout << "\tTest only first argument:" << std::endl;
MyFunction(0);
std::cout << "\tTest both arguments" << std::endl;
MyFunction(2, *test);
std::cout << std::endl;
std::cout << "Testing with MyFunction2:" << std::endl;
std::cout << "\tTest default arguments:" << std::endl;
MyFunction2();
std::cout << "\tTest only first argument:" << std::endl;
MyFunction2(0);
std::cout << "\tTest both arguments" << std::endl;
MyFunction2(2, test);
delete test;
}