Please forgive this question because it is likely along the lines of being elementary. Also, I have extensively googled this, but all I found were examples using implementations that quite obviously result in a memory leak.
Take note of the following pseudo code:
void myArbitraryFunc(){
...
// Create Pointer to parent class
MyParentClass* parent = (MyParentClass*)this.getParent();
parent->doSomething(someData);
...
}// Is parent destroyed here?
By destroyed I don't meam the parent class, I mean the pointer "parent", which I declared in the function body. It is destroyed when it falls out of scope, correct? If yes, why? And how would I create a duplicate of the class pointer without it being tied to the original parent?
The pointer parent is destroyed. What it points to, however, is not destroyed.
The pointer itself is just a variable on the stack, and goes away when the stack unwinds, when the current scope ends. It is conceptually no different from this code:
void myArbitraryFunc() {
...
int parent = 42;
....
} // parent goes away
The way to think about it is that a pointer is just a number, that number being the memory address of the object pointed to.
Now in your example, we presume that the MyParentClass object itself was created by something else, and is owned by something else, so myArbitraryFunc is not responsible for deleting it.
A pointer is really just a number, and "address" of the object. Imagine memory as a giant set of boxes, with a number. You ask the system to create an object, and it does so, and tells you that the object is in box 42. Obviously writing copies of '42' isn't doing anything to the object itself. It's just making lots of copies of the address.
Related
I'm using box2d and as you already may know, it holds a void* to an object which i can use as reference when collisions occur between different entities. Problem is that the original item is saved inside a shared_ptr since the ownership is unknown and different classes (example player class) can 'equip' another class (weapon).
I'm just wondering if its possible to put this pointer inside a shared_ptr and refer to the same object as the original one?
This is an example:
std::vector<std::shared_ptr<Environment>> listEnvironment;
listEnvironment.push_back(std::make_shared(new Weapon()));
//takes a void pointer
box2d->userId = listEnvironment.back().get();
//some shit happens somewhere else and collision occurs and I get pointer back from box2d's callback:
Environment* envPtr = static_cast<Environment*>(box2d->userId);
As you can see envPtr is going to cause trouble.
Is there a way to refer to the old smart-pointer and increase its reference value?
PS:
In actuality every class creates an box2d body which holds a 'this' pointer so i don't actually have the address to the smart-pointer either. The example above is kind narrowed down to give you a hint of the problem i'm facing.
Best regards
nilo
If Environment has std::enable_shared_from_this<Environment> as a parent class then, yes. Just call envPtr->shared_from_this().
I have a very weird and probably obvious problem, but I can't seem to find the bug. I've got a class object that holds a pointer to another class object, and when the first's deconstructer is called, it tries to delete its pointer, but instead causes a segfault without ever entering the second's deconstructor.
Specifically, I have an instance of the class Optimizer:
class Optimizer {
public:
Optimizer();
~Optimizer();
//Lot's of public methods and such
private:
PredictionRenderer *_predictionRenderer;
//Lot's of member variables
};
Optimizer::~Optimizer() {
std::cout<<"optimizer destructor:"<<_predictionRenderer->getWidth()<<std::endl;
delete _predictionRenderer; //THIS LINE CRASHES AND NEVER MAKES IT INTO THE PREDICTION RENDERER DECONSTRUCTOR
//other calls
}
(This is a big project, so for brevity I removed all the extra methods/variables).
Optimizer has a pointer to a PredictionRenderer object, _predictionRenderer. This pointer is initialized during the call to the constructor. The pointer is private, and I checked and made sure that it can't "get out" (that is, no one outside this Optimizer object can get ahold of this pointer. It is never returned by any of optimizer's methods and it is never passed to any method by an optimizer method).
When attempting to delete the Optimizer object, my program segfaults on the delete _predictionRenderer line. Execution never makes it into the PredictionRenderer deconstructor. I added in the print statement before the delete call to verify that the pointer was not NULL or already deleted, and the call to PredictionRenderer's getWidth method returns successfully, which suggests that it must be a valid pointer (is it possible to call a method of a deleted object?). Also, the print statement is only printed out once, so I'm pretty sure that the Optimizer object isn't being copied and deleted twice. Finally, the deconstructor for PredictionRenderer is never called, not by delete or anywhere else.
I have not idea what could be causing this. Does anyone have any insight into what is going on?
Edit: As I mentioned in the comments, this code base is big. I apologize for not showing much, but I can't really show everything as there just isn't enough space. This is someone else's code that I'm using, and from what I can tell, he never actually destructs this object, he just lets it get deallocated when the program quits. I could do this too, but it seems like a hack and not a good way to do business.
Are you sure there is even a _predictionRenderer to delete? You should check first.
if (_predictionRenderer)
delete _predictionRenderer;
If you try to delete a pointer that was never allocated memory, your program will crash.
nothing wrong in the lines of code you posted.
i suggest cross-check the value of _predictionRenderer ptr right after its initialization and compare it with the value you see in the Optimizer::~Optimizer(). they should be the same, if not you have a problem outside. may be your container object is corrupted.
I have the following app structure :
/// CLASS VIEW3D.h
class View3D;
typedef boost::shared_ptr<View3D> ViewSP;
class View3D
{
public:
View3D(void);
};
/// CLASS SCREENQUAD.h
class ScreenQuad
{
public:
ScreenQuad(ViewSP view);
~ScreenQuad(void);
protected:
ViewSP _viewSP;
};
/// CLASS VIEW3D.cpp
View3D::Init(ViewSP view)
{
_screenQuadSP=new ScreenQuad(view);
}
/// CLASS SCREENQUAD.cpp
ScreenQuad::ScreenQuad(ViewSP view):
_viewSP(view)
{
assert(_viewSP);
}
Now, I pass a reference of class A into class B in the form of shared pointer and keep it in a global variable A_SP. When the app shots down I am getting this:
HEAP: Free Heap block 2837920 modified at 2837b5c after it was freed
After debugging the execution I found that after the class A destructor has been called it gets called again when the destructor of class B is executed.So my guess is that the boost tries to free the memory at the address of the pointer encapsulated in _A_ref.
Just to note: the order of destruction is A class first, then B class.
How do I get around it? Shouldn't shared_ptr keep the ref count and not to trigger destructor of the object which has already been released?
Your code is still too incomplete the show the problem, but I can think of a few common causes for such an error.
You explicitly delete your View3D instance somewhere. Don't do that, the shared_ptr will. If you no longer need the object, you can call ptr.reset(), which will decrease its reference count and delete it if appropriate. (This happens automatically when a shared_ptr is destroyed, e.g. in your ScreenQuad destructor; in that case there's no need to do it explicitly.)
You accidentally created multiple reference counters for the same object. There should be only one spot where you create a shared_ptrfrom a View3D* raw pointer, namely at the same place where the object is created. Everywhere else, you have to create your shared pointers from other shared (or weak) pointers. Otherwise you'll end up with multiple reference counters, and each of these will eventually try to delete the object, even if it has been freed already.
You created a shared_ptr to an object on the stack. Essentially, that's the same problem as calling delete on a stack-allocated object.
This might help you find the error yourself, otherwise you really need to post more code – as far as I can see nothing of this happens in the snippets you showed so far.
I have two four classes:
MainClass (class where things start)
XmlReader (class used to parse an xml file)
SerialPortSettings (holds info about the serial port read from the xml-file, e.g. baud rate, comport etc)
SerialPortListener (takes a reference to a SerialPortSettings object in its constructor)
MainClass has a method to read things from an xml-file.
In this method, it first creates an instance of XmlReader and gives it an xml-file as a constructor parameter. This xmlReader does only need to exist within this method:
XmlReader xmlReader (xmlFile);
The xmlReader parsers the xmlFile. MainClass gets access the xml-stuff by calling get-methods in XmlReader. So far everything is good.
However, one of the methods XmlReader offers, is a method which creates an object of type SerialPortSettings based on the information read from the xml-file:
SerialPortSettings* XmlReader::getSerialPortSettings() {
.... // reading stuff from xml file
return new SerialPortSettings(baudRate, dataBits, comport);
}
This method is called from MainClass and the return value is stored in a pointer:
SerialPortSettings* settings = xmlReader.getSerialPortSettings();
The next thing the MainClass does is to create a SerialPortListener (which is a member-variable that has to exist until MainClass is exited). SerialPortListener takes a reference to a SerialPortSettings in it's constructor:
m_serialPortListener = new SerialPortListener(*settings);
Hence SerialPortSettings also has to exist until MainClass exits, therefore I have created this as a pointer.
So here is the clue:
In the SerialPortListener destructor I tried to delete the SerialPortSettings-object:
SerialPortListener::~SerialPortListener() {
delete &m_settings;
}
Then in the MainClass destructor I deleted the SerialPortListener-object:
MainClass::~MainClass() {
delete m_serialPortListener;
}
This fails. I get an error saying that I deleted something twice in the main-class:
*** glibc detected *** ./ioserver: double free or corruption (out): 0x00860d80 ***
When I remove the delete &m_settings from SerialPortListener, it works fine.
But when should pointer be deleted? What is the correct thing to do? I really want my xml-reader to create the SerialPortSettings - object, insted of returning all of the info (baud rate, comport etc) to MainClass and create the SerialPortSettings object itself.
A good solution is to simply let xmlReader::getSerialPortSettings return a SerialPortSettings by value.
Let the compiler do the optimization.
But where you do need to handle pointer lifetimes, do use smart pointers, such as std::auto_ptr or boost::shared_ptr. The key idea is to define ownership. The owner (which in the case of boost::shared_ptr is the collection of smart pointers referring to the object) is responsible for deleting – no-one else.
Cheers & hth.,
The pointer should be deleted at the end of MainClass.
It makes no sense (to me, at least) to use delete on a reference.
It would be way cleaner to not have the XML reader create new objects; treat SerialPortSettings as a "dumb" container, and just pass in a reference to fill in with data from the XML:
XmlReader::getSerialPortSettings(SerialPortSettings& settings);
the actual instance can then be a local variable in the main program, and be passed (by const reference, this time) to the serial port when it's created:
SerialPortSettings portSettings;
m_xmlReader->getSerialPortSettings(portSettings);
m_serialPort = new SerialPort(portSettings);
the life time of the settings instance is then naturally the same as the scope it's in, since it's just a local variable.
If the method in the main class that reads XML needs to exit before the serial port goes out of scope, you could make the settings a member variable of the main class, instead.
What is the datatype of m_settings? Is it a SerialPortSettings* or a SerialPortSettings? If the latter, you can't delete it like that anyway, as it's allocated on the stack. If it's the former (a pointer), you do not need the reference operator. Simply write delete m_settings;
A simple typo in your delete:
delete &m_settings;
should be:
delete m_settings;
For any pointer you should decide who owns the pointer, and that should be who deletes it.
Or you can use a smart pointer such as shared_ptr and eliminate the problem altogether.
SerialPortListener::~SerialPortListener() {
delete &m_settings;
}
That block looks quite weird. Are you sure you aren't trying to delete value by reference? Cause C++ does it automatically when you delete the class, so your delete is really trying to delete twice.
OK, first of all, you're missing the truly important bit of information which is HOW is SerialPortListener::m_settings being stored. Because of the error you're getting, I'm guessing you're actually storing a copy of it, which means: I bet you have something like this:
class SerialPortListener {
SerialPortSettings m_settings;
SerialPortListener(SerialPortSettings set) {
m_settings = set;
}
}
if it's something similar to this, then the listener is saving a copy of the object in it's own memory, and deleting it doesn't make sense, since it's not a pointer. Rule of thumb, never do delete &anything until you know what you're doing and realize you really need to.
In terms of "correctness", the pointer should be freed by the main class, since it was who created it. Or if you don't have any use for it in the main class, and want the listener to delete it, save a pointer instead of an object or reference in the listener.
I ended up making m_serialPortSettings a pointer in SerialPortListener, and deleting it from there.
I have a C++ class where I have a dynamically-allocated array of pointers to structs. I have a member function to "add an item" to this array by assigning an index of the array to the pointer to a dynamically allocated instance of the struct.
I have sort_arr initialized with sort_arr = new node *[this->max_items];.
In my assignment function I have sort_arr[this->num_items] = item; where the pointer is being passed as an argument with node *item.
In this function, I am able to access a member variable using (*sort_arr[i]).key_a (where i is the index), but once another item is added, this reference is no longer valid and causes a seg fault.
Is the pointer being deallocated, and if so, is it possible to prevent this?
EDIT: Sorry for the ambiguity here. I am trying to understand the problem generally and not specifically (in a pedagogical sort of way). I was hoping it was a problem with my conceptual approach. Given that it probably isn't, here are some more details:
node is defined as node **sort_arr; in the class declaration and then initialized by the constructor as sort_arr = new node *[this->max_items];. The insert method of the class executes: sort_arr[this->num_items] = item;, where item is passed with node *item.
It seems that after an item 'n2' is inserted after 'n1', 'n1' is no longer accessible via the reference (*sort_arr[num_items]).key_a. key_a is a member variable of the node struct.
EDIT 2: node *item is dynamically allocated outside of the class (in the main function).
The code you posted looks basically correct (if not the best way to do this sort of thing), but I can't tell what key_a is, or what context you are calling it in. Because of that, it's hard to tell exactly what the problem is. Posting the entire body of your function might be useful.
The only way something you allocated via new will be deallocated is if you (or some code you call) explicitly calls delete. That's pretty much the whole point of dynamic memory allocation, to allow your objects to live after the stack frame gets popped off.
My best guess with the current information is that you're trying to access a local value that got allocated on the stack after returning from the function. For example, this would cause a problem:
some_type* some_function(int i)
{
// ...
some_type p = (*sort_arr[i]).key_a; // p is a copy of key_a, allocated on the stack
// ...
some_type* result = &p;
return result;
}
In this scenario, p would be okay to return directly (if you changed the return type to some_type instead of some_type*), but you can't return a pointer to a local value. The local value is no longer valid after the function exits. This often causes a segfault.
Make sure that this->num_items as well asi is less than this->max_items and greater than -1, as this could be the cause of seg-fault.
Don't use dynamic arrays if it isn't for lecturing. Use a simple and save std::vector. It handles nearly everything that could go wrong. Try with that and see if there's still a seg-fault.
As noted, the code does appear to be correct. The problem was unrelated to the referenced code. I had been debugging some memory leaks and was deleting the referenced items, which was in turn causing the problem (quite obviously now that I see that).
I appreciate everyone's help and I'm sorry if I drove anyone crazy trying to find what was wrong.