Array of pointers holds the same value for all elements - c++

I'm currently deep-diving into the way pointers work.
Something for me unexplainable happened when executing the following lines of code:
std::vector<OptimizerPlanOperatorPtr> sources;
for (const auto &source : sourceOperators){
OptimizerPlanOperator planOperator = OptimizerPlanOperator(source);
sources.push_back(static_cast<std::shared_ptr<OptimizerPlanOperator>(&planOperator));
}
all sourceOperators differ, however when checking the elements of sources, they all point to the same OptimizerPlanOperator.
When I ran the debugger, I realized that in every loop step, all values of sources
change to the recent value.
My assumption is, that I poorly initialized the pointer here which somehow results in the value the pointer refers to being overridden.
Can somebody show a solution or explain, what I did wrong here?

You are storing the location of an object whose lifetime ends with the current iteration and handing ownership of it to a shared_ptr. Both are problems that lead to undefined behaviour.
Casting a pointer to std::shared_ptr does not automagically make the pointed-to object into a shared object and extend its lifetime, and it is equivalent to std::shared_ptr<OptimizerPlanOperator>(&planOperator).
The simplest solution is to not do this stepwise but all at once:
for (const auto &source : sourceOperators){
sources.push_back(std::make_shared<OptimizerPlanOperator>(source));
}

Your planOperator is a local variable on the stack, and when you are passing it to the cast static_cast<std::shared_ptr<OptimizerPlanOperator>(&planOperator), you are passing in the address of a local variable, so as soon as the iteration is over, that pointer &planOperator becomes garbage.

Related

C++ references and exiting scoping

I'm getting to grips with references in C++ and I have a small query surrounding references & scoping, for this it's probably best to create an example:
Imagine I have a method in "BankDatabase.cpp" which takes a bank record by reference and adds it to a data structure (also by reference).
void AddRecord( BankRecord& bankRecord )
{
//Add record to data structure by reference
}
If I run a method like so:
void TestAddRecord( BankDatabase& bankDatabase )
{
BankRecord bankRecord { "John", "Doe", 9999 }
bankDatabase.AddRecord( bankRecord );
}
To my mind, "bankRecord" falls out of scope (as do its two strings and int) and is thus cleared from memory at the end of the "TestAddRecord" method, leaving "bankDatabase" pointing at some empty memory?
If so what's the general accepted standard / resolution to such a scenario? It seems a little mad to have to pass things by value...
In that case passing by value seems like the way to go. Allocating a new BankRecord pointer will work too. Storing things by reference is not very great.
However if I'm not mistaking, your two strings and the int won't be lost since they are present in the stack and will not be deallocated. But bankRecord will still be lost.
The best way to answer these concerns is to step through the code in the debugger and see what the Vector is doing with the variable being appended. Look especially at the constructor calls as you step into the data structure's Append functions. Because I do not know your underlying data structure, it is a bit more difficult for me to tell you more information. I will assume it is a std::vector for now until told otherwise.
You may be surprised to learn that references passed through a function do not tell the entire story about when it will go in and out of scope. I often think of C++ references as pointers that do not need nullptr checks.
Your code will work fine as long as the reference is copied into the vector or does not go out of scope because the variable it pointed to was destroyed. The reference will not go out of scope if it is referring to a member variable or memory on the heap for your particular case.
If the reference was declared on the stack to a variable created on the stack, and then appended to the vector, then you will have scope problems.
You should also look into emplace() if you have C++11 and the compiler supports move semantics.
In short, the most important thing you can do here is step through the code and see what Constructors are being called. This will give you the answer you desire.

Reason to have a member reference variable over a member pointer variable

What is a practical example and reason to store a reference to an object instead of a pointer? The obvious reason I can come up with is to avoid memory management.
I've come across a library where sometimes a class will store an object by reference and sometimes by pointer and it's difficult for me to understand why and when to use one over the other?
Example:
class EventBusDemo : public Object
{
private:
HandlerRegistration* playerMoveReg;
};
class PlayerMoveEvent : public Event
{
private:
Player& player; // Why not a pointer here?
};
The key points are that the identity of the object a reference points to can not be changed (its values can though), and a reference can not be null (but you can still get dangling references if you're not careful)
So if you see code like this:
class ObjectWithPointer
{
private:
Object* object;
};
You might need to do this:
void useIt(ObjectWithPointer & value) {
if(value.object!=NULL) {
doSomethingWith(*value.object);
}
}
And you can also do this:
void modifyIt(ObjectWithPointer & value) {
value.object!= some_object_ptr;
}
However if you have this:
class ObjectWithRef
{
private:
Object& object;
};
The first example becomes:
void useIt(ObjectWithRef & value) {
doSomethingWith(value.object);
}
And the a naive conversion of the second
void modifyIt(ObjectWithRef & value) {
value.object=some_object;
}
does something completely different - it copies the value of some_object into the reference, but there is no way to cause the reference to point somewhere else.
The better question is "Why would you use a pointer instead of a reference?". Generally, you should only use a pointer when you can actually answer this question.
For the purposes of referring to something, a pointer requires slightly more cumbersome syntax to use. Also, you can do more with a pointer than you can with a reference, like change where it's pointing, which is a Bad Thing if you aren't actually doing any of that. Any savvy reader who sees your pointer will be forced to consider all sorts of things that they wouldn't do if you had used a reference, like wonder if you remembered to initialized it, or wonder if you change what it's pointing to, et cetera.
It probably impairs compiler optimizations too, since the compiler has to wonder about the same things!
I think it is almost always matter of taste. You can use reference for class members when you want emphasize that one object is not owner of other object or if you want avoid runtime check for null-pointer. Every approach has cons and pros, but in my practice I avoid use reference as object members because you can't reassign their values.
If you see in class X a reference to object rather than pointers, X can be happy to think that the object is local. It is somewhere in the stack. X does not have to think about its destruction definitely. With pointers, the object would be on the heap. Programmer (and especially maintainer of X) might get confused about who would free this pointer. So, peace of mind with references. This point is valid when comparing reference-to-object-on-heap and pointer-to-object-on-stack.
There comes then another problem, dangling references and dangling pointers.
Since, anybody can call a delete on a pointer from any place, it is difficult to find the actual cause of dangling pointers. Not with dangling references. Since, that object would be destroyed when it went out of stack, there is only one place in code where that can happen (it is where that object was created).
So, it is easier to find the problem.
If you get a dangling reference, there is something wrong in design. As you are storing an object Y's reference in X. X is using Y. However, lifetime of X is greater than Y. This can happen when Y is local and X is global. This is counter-intuitive because why would in the stack you would store the reference of upper-stack-object in lower-stack-object.
But with dangling pointers, there can be wrong logic-error or ownership mismatch. So, if problem like dangling reference comes, it can be fixed with better design.
However, if we are storing the object on heap as a reference, it would be difficult to find the dangling-reference problem again.
So, my priority would be :
references to stack object > references to heap object > pointers.
Looking at your code and guessing : EventBusDemo is like some global bus that stores the registration-handler that would be called. Here this is one object and you would be giving it different playerMoveReg over time. So, it is a pointer.
PlayerMoveEvent looks like it would be processed soon as it is an Event. You would create a new PlayerMoveEvent for a new event. So, do you want to make player a pointer or a reference. Do you want to change the player in a event (even by mistake) ? Definitely not. Do you want some piece of mind ? Definitely yes. So, use a reference.
If you use a pointer then:
void PlayerMoveEvent::Foo()
{
// can it be null? its possible because its a pointer!
if (player) player->bar();
}
PlayerMoveEvent::~PlayerMoveEvent()
{
// crash? or memory leak with out?
delete player;
}
A reference makes it clear that it will be valid for the life time of the object (or at least that is the intention) and that you do not own the object. Always use a reference unless a pointer is really required.

How to pass std::unique_ptr around?

I am having my first attempt at using C++11 unique_ptr; I am replacing a polymorphic raw pointer inside a project of mine, which is owned by one class, but passed around quite frequently.
I used to have functions like:
bool func(BaseClass* ptr, int other_arg) {
bool val;
// plain ordinary function that does something...
return val;
}
But I soon realized that I wouldn't be able to switch to:
bool func(std::unique_ptr<BaseClass> ptr, int other_arg);
Because the caller would have to handle the pointer ownership to the function, what I don't want to. So, what is the best solution to my problem?
I though of passing the pointer as reference, like this:
bool func(const std::unique_ptr<BaseClass>& ptr, int other_arg);
But I feel very uncomfortable in doing so, firstly because it seems non instinctive to pass something already typed as _ptr as reference, what would be a reference of a reference. Secondly because the function signature gets even bigger. Thirdly, because in the generated code, it would be necessary two consecutive pointer indirections to reach my variable.
If you want the function to use the pointee, pass a reference to it. There's no reason to tie the function to work only with some kind of smart pointer:
bool func(BaseClass& base, int other_arg);
And at the call site use operator*:
func(*some_unique_ptr, 42);
Alternatively, if the base argument is allowed to be null, keep the signature as is, and use the get() member function:
bool func(BaseClass* base, int other_arg);
func(some_unique_ptr.get(), 42);
The advantage of using std::unique_ptr<T> (aside from not having to remember to call delete or delete[] explicitly) is that it guarantees that a pointer is either nullptr or it points to a valid instance of the (base) object. I will come back to this after I answer your question, but the first message is DO use smart pointers to manage the lifetime of dynamically allocated objects.
Now, your problem is actually how to use this with your old code.
My suggestion is that if you don't want to transfer or share ownership, you should always pass references to the object. Declare your function like this (with or without const qualifiers, as needed):
bool func(BaseClass& ref, int other_arg) { ... }
Then the caller, which has a std::shared_ptr<BaseClass> ptr will either handle the nullptr case or it will ask bool func(...) to compute the result:
if (ptr) {
result = func(*ptr, some_int);
} else {
/* the object was, for some reason, either not created or destroyed */
}
This means that any caller has to promise that the reference is valid and that it will continue to be valid throughout the execution of the function body.
Here is the reason why I strongly believe you should not pass raw pointers or references to smart pointers.
A raw pointer is only a memory address. Can have one of (at least) 4 meanings:
The address of a block of memory where your desired object is located. (the good)
The address 0x0 which you can be certain is not dereferencable and might have the semantics of "nothing" or "no object". (the bad)
The address of a block of memory which is outside of the addressable space of your process (dereferencing it will hopefully cause your program to crash). (the ugly)
The address of a block of memory which can be dereferenced but which doesn't contain what you expect. Maybe the pointer was accidentally modified and now it points to another writable address (of a completely other variable within your process). Writing to this memory location will cause lots of fun to happen, at times, during the execution, because the OS will not complain as long as you are allowed to write there. (Zoinks!)
Correctly using smart pointers alleviates the rather scary cases 3 and 4, which are usually not detectable at compile time and which you generally only experience at runtime when your program crashes or does unexpected things.
Passing smart pointers as arguments has two disadvantages: you cannot change the const-ness of the pointed object without making a copy (which adds overhead for shared_ptr and is not possible for unique_ptr), and you are still left with the second (nullptr) meaning.
I marked the second case as (the bad) from a design perspective. This is a more subtle argument about responsibility.
Imagine what it means when a function receives a nullptr as its parameter. It first has to decide what to do with it: use a "magical" value in place of the missing object? change behavior completely and compute something else (which doesn't require the object)? panic and throw an exception? Moreover, what happens when the function takes 2, or 3 or even more arguments by raw pointer? It has to check each of them and adapt its behavior accordingly. This adds a whole new level on top of input validation for no real reason.
The caller should be the one with enough contextual information to make these decisions, or, in other words, the bad is less frightening the more you know. The function, on the other hand, should just take the caller's promise that the memory it is pointed to is safe to work with as intended. (References are still memory addresses, but conceptually represent a promise of validity.)
I agree with Martinho, but I think it is important to point out the ownership semantics of a pass-by-reference. I think the correct solution is to use a simple pass-by-reference here:
bool func(BaseClass& base, int other_arg);
The commonly accepted meaning of a pass-by-reference in C++ is like as if the caller of the function tells the function "here, you can borrow this object, use it, and modify it (if not const), but only for the duration of the function body." This is, in no way, in conflict with the ownership rules of the unique_ptr because the object is merely being borrowed for a short period of time, there is no actual ownership transfer happening (if you lend your car to someone, do you sign the title over to him?).
So, even though it might seem bad (design-wise, coding practices, etc.) to pull the reference (or even the raw pointer) out of the unique_ptr, it actually is not because it is perfectly in accordance with the ownership rules set by the unique_ptr. And then, of course, there are other nice advantages, like clean syntax, no restriction to only objects owned by a unique_ptr, and so.
Personally, I avoid pulling a reference from a pointer/smart pointer. Because what happens if the pointer is nullptr? If you change the signature to this:
bool func(BaseClass& base, int other_arg);
You might have to protect your code from null pointer dereferences:
if (the_unique_ptr)
func(*the_unique_ptr, 10);
If the class is the sole owner of the pointer, the second of Martinho's alternative seems more reasonable:
func(the_unique_ptr.get(), 10);
Alternatively, you can use std::shared_ptr. However, if there's one single entity responsible for delete, the std::shared_ptr overhead does not pay off.

c++ vector push_back with pointers

I'm trying to get my head around solving the following problem. I have the following function which accepts a const reference to an object. What I want to do, is give storage, a pointer to the object component is referencing. However, when I call storage.push_back() changes the object component is referencing (it's member data gets corrupted)
I'm just trying to store a pointer to the same object component is referencing, not alter the object at all.
void InputSystem::RegisterInputAcceptingEntity(const PlayerInputComponent &component) {
auto *cpy = &component;
std::vector<const PlayerInputComponent*> storage;
storage.push_back(cpy);
}
Why would the above code at all change the object component is referencing?
edit: Ok I edited the vector to contain constant pointers.
Here are some screenshots showing exactly what is happening. Here in the callee, if we inspect the argument that is going to be passed by reference, we can see the input_component member is not corrupted.
url to image: http://i.imgur.com/lKpRm.png
However, in the second image, just after stepping into the above said method:
url to image: http://i.imgur.com/x0Vdn.png
I've been under the impression that passing by const reference, there should be no way for the objects to differ inside/outside the function. I don't see why the object would be altered at all, if passed by const reference.
First, run your code through valgrind and see where the corruption is actually occurring. Pushing a pointer onto an array should not do anything to the data being pointed to.

C++ Pointer (Pass By Reference) Question

A pointer that is passed-in-by-reference. Why? aren't pointers just references anyways? What's really happening to this parameter?
void someFunc(MyPtr*& Object)
{
}
Simply speaking, it gives you the ability to change the pointer itself: it can be changed to point to another location in the function.
And the change will be reflected outside.
It enable you to:
void someFunc(MyPtr*& Object)
{
//Modify what Object is pointing to
Object=&old_Object;
//You can also allocate memory, depending on your requirements
Object=new MyPtr;
//Modify the variable Object points to
*Object=another_object;
}
Other's will have to vote to verify this cause I'm a bit rusty on my C++ but I believe the idea here is you'd pass in a pointer by reference, that is instead of creating a new space to store the pointer itself you use a reference to the pointer so if you were to modify the pointer not just the value it would be modified after returning from the function, whereas otherwise all you could do is modify the value at position passed in. Hope that makes sense.
The difference to passing just a pointer is that if the pointer is changed (Object = x) then this change will be seen by the calling function. You could achieve the same when you pass MyPtr** Object and dereference the pointer *Object = x;. With the second approach you could pass NULL to the function. This is not possible for references.
You are not quite right. The pointer content is passed by reference but the pointer itself is still passed by value, i.e. reassinging it to some other pointer will not be reflected upon the exit from the method because the pointer will be set to point to the same memory block as before the call. Think of it as a simple int variable. However with &* or ** you can reassign the pointer and that will be visible outside the scope of this method.
Why?
For the same reason that you would pass in anything else by reference.
aren't pointers just references anyways?
Dear god, no. Not even remotely the same thing. Look, you can try to build a mental model of a reference by starting with a pointer, but by the time you've fixed up all the differences, you have a horrible illogical mess.
References are a much simpler and more intuitive concept, and there are only "historical reasons" for trying to understand pointers before them. Modern C++ uses raw pointers only rarely, and treats them as an implementation detail as much as possible.
A reference is another name for an already-existing thing. That's it. When used as a function parameter, they thus allow the called function to refer to the caller's data.
It also means the pointer can be 0 (NULL) which can having meaning to the method. A reference must always be valid and cannot be made 'nothing'