c++ Delete a list of pointers - c++

I have this class-object in c++ (using Qt):
class Foo {
public:
Foo();
~Foo();
QList<Bar*> barList;
}
My question is: do I need to delete every Bar object in the barList in the destructor (for loop), or since the list is a static object everything will be deleted with the Foo object ?
Thank you.

You can use qDeleteAll(...) (which is basically a foreach over your list and calling delete on every item inside). Do not use QList::clear() which simply removes the items from the list but doesn't trigger deallocation. You can however combine the two to first release the memory of the objects your list items (pointers) are referencing and then use clear() to remove the items (pointers) themselves from the list leaving you with an empty barList.
In addition to that if Bar is derived from QObject you can just set its parent to another object/widget which you are sure will be properly released at some point. This is the parent-child model in Qt and is a nice way to clean stuff without the need to take care of the deletion yourself.
Also static here is incorrect. I think you mean on the stack that is your barList is not dynamically allocated.
A word of caution: even though you have Bar* this does not mean that the items themselves are dynamically allocated. You can have items created on the stack and then append them by reference to your least which in terms will lead to segmentation fault if you try to delete them. Since you don't provide more code I can't say if your Bar*s are dynamically allocated or not.
Of course it really depends on what Bar represents so the second suggestion might not be proper for the given scenario.
Btw your question shows a general lack of understanding how pointers work and is in fact not Qt related (even though your problem here is in the context of Qt). My suggestion for you would be to look up some general information on pointers in C/C++ and then move onto the containers provided by Qt.

Related

C++: Can someone explain generally how to design/write a destructor for an abstract data type?

thanks in advance for any help you can give. I am struggling with figuring out what exactly goes into a destructor because I haven't found a great explanation of really how you implement the idea with code. My textbooks and a couple of different things I've read explain that a destructor is essentially a method that is called for an abstract data type (ADT) that helps to release any resources/memory used by an ADT object. My textbook code example though literally just has a cout statement inside of the destructor that says "The object is about to be destroyed" which you can imagine isn't particularly helpful.
I am working on a stacks project where we're creating a stack of pointers to a struct object called Data (which does not have a destructor, read a little bit about why that is earlier) which contains two attributes: int ID and string data. Then the stack itself only has two attributes: int top (holds the top value for peek and pop functions) and the array of Data pointers.
So do I need to delete top and delete the stack of pointers? Can I just delete the stack of pointers as a whole or do I need to iterate through the stack and delete everything inside of it before deleting the stack array itself? If I do need to delete each pointer, can I just delete the pointer? Or do I need to figure out how to also delete the information that is inside of that memory location where the pointer is pointing? And do I do all of those things using the delete keyword?
Just trying to wrap my head around what all I need to specifically target when deleting things in the destructor. Once I know that much, I think that I can figure out how to do the actual writing by googling for syntax and testing out in the IDE/terminal, double checking things with the professor if syntax isn't quite working, etc.
Normally I'd ask these things to my professor in class, but the class itself is for data structures and algorithms so I don't want to interrupt those topics to ask something that feels sort of regressive. I think maybe these things were supposed to be covered in the prerequisite course but I took that class a while ago and it doesn't seem that these things were really covered well based on that textbook I still have (and there was no lecture because it was online).
I really want to learn these concepts deeply and understand the architecture behind them as much as possible so that I'm prepared well for writing good code and working in a professional environment. Thank you again for any help you all can give!
To requote your questions:
So do I need to delete top and delete the stack of pointers? Can I just delete the stack of pointers as a whole or do I need to iterate through the stack and delete everything inside of it before deleting the stack array itself? If I do need to delete each pointer, can I just delete the pointer?
That really depends on how you implemented your array of pointers, if each pointer has is not pointing to another array, list, or some object of some kind, and given your array is a static array then, simply typing delete arrayName[] is fine. But if your pointers point to another array or list or object of some kind, then you would need to set variables for those objects or list or array to their default values and delete them one by one.
Here are the three ways to write a destructor for an abstract class:
The class may be deleted polymorphically:
class BaseClass
{
public:
virtual ~BaseClass() = default;
};
The class may be used polymorphically, but deletion always uses the exact runtime type (e.g. std::make_shared() acts this way)
class BaseClass
{
protected:
/* not virtual */ ~BaseClass() = default;
};
The class is just a fancy namespace (namespaces are missing some features) and is used as a container but never instantiated:
template<stuff> class FancyNameSpace
{
private:
/* virtual doesn't matter */ ~FancyNamespace() = delete;
};
A class hierarchy should always be using the compiler-generated default destructor, with only changing the access and virtualness. That's because acting as a base class is a separate responsibility from managing a resource, so the Single Responsibility Principle says that the resource management should be moved to a helper class whose sole function is scope-based resource management (RAII).

Program design concerning polymorphism & resource management

I have a class called Widget. This class is abstract and has virtual methods. To avoid object slicing all Widgets are stored as references or pointers. I have several classes with constructors that store internally the widget given to them; thus the Widget stored must have been initialized outside the constructor and cannot be destroyed before the object is, therefore usually the Widget is allocated via dynamic memory. My question is regarding how to handle this dynamic memory; I have compiled a list of options (feel free to suggest others.) Which is the most idiomatic?
1. Smart pointers. Smart pointers seem like the right choice, but since I'm using C++98 I have to write my own. I also think that writing smart_pointer<Widget> all the time is a little ugly.
2. Copy Widgets when stored. Another course of action is to store a copy of the passed-in Widget instead of the original. This might cause object-slicing, but I'm not sure. Also, users might want to write classes themselves that store passed-in Widgets, and I wouldn't want to make it too complicated.
3. Let the user handle everything. I could perhaps make the user make sure that the Widget is deleted on time. This seems to be what Qt does (?). However, this again complicates things for the user.
I personally like this approach (it is not always applicable, but I used it successfully multiple times):
class WidgetOwner
{
vector<Widget*> m_data;
public:
RegisterWidget(Widget *p) { m_data.push_back(p); }
~WidgetOwner() { for (auto &p : m_data) delete p; }
};
This simple class just stores pointers. This class can store any derivatives of Widget provided that Widget has virtual destructor. For a polymorphic class this should not be a problem.
Note that once Widget is registered, it cannot be destroyed unless everything is destroyed.
The advantage of this approach is that you can pass around pointers freely. They all will be valid until the storage will be destroyed. This is sort of hand made pool.
Which is the most idiomatic?
The most idiomatic would certainly be what next versions of c++ decided to be "the way to go", and that would be smart pointers (You can find/use an implementation on boost for example, also other ones on the internet might be simpler for inspiration).
You can also decide that since you are using c++98 (that's a huge factor to take into consideration), you take what's idiomatic for that context, and since that was pretty much no man's land, the answer is most likely whatever home made design is the most appealing to you.
I think smart pointer is best choice. And if you feel template is ugly, try the typedef

Is there any way to use Qt without using dynamic memory for everything?

So, I think I've searched the web quite thoroughly about this and found nothing really useful (just confusing at most...).
I'd like to know how I can (if possible) use Qt with non-dynamic memory. The problem I face is that for many widgets, I know exactly what I want to use (these sub-widgets, these layouts, in fixed numbers, etc.). Yet, everything in Qt seems to get in the way when you don't use dynamic memory. A simple example is QLayout, which from the Qt documentation is designed to take ownership of anything it is added. So basically, the following code:
//In header
class ThumbnailDialog : public QDialog
{
Q_OBJECT
public:
ThumbnailDialog(QWidget* parent = 0);
~ThumbnailDialog(void);
private:
QPushButton m_confirm;
QPushButton m_cancel;
QHBoxLayout m_buttonsLayout;
};
//Implementation of ctor
ThumbnailDialog::ThumbnailDialog(QWidget* parent):
QDialog(parent)
{
//...
m_buttonsLayout.addWidget(&m_confirm);
m_buttonsLayout.addWidget(&m_cancel);
//...
setLayout(&m_dialogLayout);
}
...will end up (on MSVC) in a debug assertion fail for _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) because, in the ThumbnailDialog's dtor, the layout tries to delete the buttons... which it obviously shouldn't.
So, am I forced to use dynamic memories everywhere, as this "Qt Expert" advocates (while mentioning "heap", though...) ? This seems wrong as this prevents taking advantage of RAII (if parent-child relation means there'll be a delete, one can't use smart pointers to do that I suppose, then). It also feels terribly wrong to resort to dynamic memory for things known at compile-time... (but I could be wrong, that's just my feeling).
So: is there any way of using Qt without resorting to dynamic memory and news for every single widget/layout ?
I think you are misunderstanding the problem here. You are not double deleting something, you are deleting an object allocated on the stack:
int foo = 12345;
int* pFoo = &foo;
delete pFoo;
This is what happens when you pass a pointer to a stack based object to QHBoxLayout, hence your heap corruption debug assert.
Qt manages QObjects this way because most GUI's have LOTS of widgets, which makes managing GUI object life times easier, it also allows queued deletes across threads etc. Also internally most classes use PIMPL's so you are not avoiding the heap/dynamic allocation even if your code worked.
Having said all this you can get it to work without the heap alloc if you wish, but it is far more effort than its worth. In your example you would have to remove the widgets from the layout in the destructor, but be sure the nullptr check things in case the ctor has thrown, if they're not in the layout when its destructor is hit then it won't be able to delete them.
One more thing to think about.. if Qt was designed to work this way then you could easily end up in the situation where you overflow the stack on some platforms. E.g Qt works on Symbian/S60 which has extremely limited stack, running your code there could easily cause a stackoverflow :).
Yes, there is. (and in a pretty clean way, I believe)
You just have to be aware about the order of destruction of your QObject hierarchy:
As explained in the Qt docs, a lot of objects claim ownership of their children and therefore want to make sure they get cleaned up when they die.
QObject’s dtor relieves its parent of that ownership.
Destruction of non-static data members happens from bottom to top.
Which means that, in your case, you just have to move the layout to the top:
private:
QHBoxLayout m_buttonsLayout;
QPushButton m_confirm;
QPushButton m_cancel;
All the layout’s children’s dtors unregister themselves from the layout, so when the layout destruction happens there are no registered childs left.
Previously the layout’s destruction deleted the children which where not newd in the first place.
This may seem tedious at first sight, but in practice the hierarchy within a custom widget is pretty flat. The order of widgets in one layer of the hierarchy – in this case the QPushButtons – is not important which usually means that you only have to arrange the layouts on top properly.
The problem you're seeing is that you're not thinking about what is happening. The QPushButton instances in the class are created and owned by the class. When the class is deleted, it will call the destructor on the QPushButtons.
Qt provides useful parenting of objects and deleting a parent will handle deletion of all its child objects.
So, in the case of your example, you have two things that are going to call the destructor on the QPushButtons: 1) The deletion of the class object for ThumbnailDialog and 2) The deletion of the buttonlayout, which will try to delete its children and will fail, as the object is on the stack.
What you can do, if you really want, is ensure that the QPushButton items are removed from the button layout, in the destructor of ThumbnailDialog by calling removeWidget() on the button layout.
However, this is messy. Dynamic allocation is a much better method, as it allocates objects on the heap and not the stack.
Also note, with Qt's parenting, it means that you can create a lot of widgets without needing to keep track of them. For example, you can do this: -
ThumbnailDialog::ThumbnailDialog(QWidget* parent):
QDialog(parent)
{
//...
m_buttonsLayout.addWidget(new QPushButton("Confirm"));
m_buttonsLayout.addWidget(new QPushButton("Cancel"));
//...
setLayout(&m_dialogLayout);
}
In this case, the push buttons don't even need to be defined in the header and you can be assured that they'll be deleted along with their parent.
No, not really. I'm afraid. Qt relies on this stuff.
If you have read the other answers and you still want to use static allocation, you can release the ownership that was taken when doing addWidget():
//...
m_buttonsLayout.addWidget(&m_confirm);
m_buttonsLayout.addWidget(&m_cancel);
// release the ownership by setting no parent
m_confirm.setParent(0);
m_cancel.setParent(0);
//...

Dynamically allocated list in C++

I made a cute generic (i.e. template) List class to handle lists in C++. The reason for that is that I found the std::list class terribly ugly for everyday use and since I constantly use lists, I needed a new one. The major improvement is that with my class, I can use [] to get items from it. Also, still to be implemented is an IComparer system to sort things.
I'm using this List class in OBJLoader, my class that loads Wavefront .obj files and converts them to meshes. OBJLoader contains lists of pointers to the following "types": 3D positions, 3D normals, uv texture coordinates, vertices, faces and meshes. The vertices list has objects that must be linked to some objects in all of the 3D positions, 3D normals and uv texture coordinates lists. Faces link to vertices and meshes link to faces. So they are all inter-connected.
For the sake of simplicity, let's consider that, in some context, there are just two lists of pointers: List<Person*> and List<Place*>. Person class contains, among others, the field List<Place*> placesVisited and the Place class contains the field List<Person*> peopleThatVisited. So we have the structure:
class Person
{
...
public:
Place* placeVisited;
...
};
class Place
{
...
public:
List<People*> peopleThatVisited;
};
Now we have the following code:
Person* psn1 = new Person();
Person* psn2 = new Person();
Place* plc1 = new Place();
Place* plc2 = new Place();
Place* plc2 = new Place();
// make some links between them here:
psn1->placesVisited.Add(plc1, plc2);
psn2->placesVisited.Add(plc2, plc3);
// add the links to the places as well
plc1->peopleThatVisited.Add(psn1);
plc2->peopleThatVisited.Add(psn1, psn2);
plc3->peopleThatVisited.Add(plc3);
// to make things worse:
List<Person*> allThePeopleAvailable;
allThePeopleAvailable.Add(psn1);
allThePeopleAvailable.Add(psn2);
List<Place*> allThePlacesAvailable;
allThePlacesAvailable.Add(plc1);
allThePlacesAvailable.Add(plc2);
allThePlacesAvailable.Add(plc3);
All done. What happens when we reach }? All the dtors are called and the program crashes because it tries to delete things two or more times.
The dtor of my list looks like this:
~List(void)
{
cursor = begin;
cursorPos = 0;
while(cursorPos < capacity - 1)
{
cursor = cursor->next;
cursorPos++;
delete cursor->prev;
}
delete cursor;
}
where Elem is:
struct Elem
{
public:
Elem* prev;
T value;
Elem* next;
};
and T is the generic List type.
Which brings us back to the question: What ways are there to safely delete my List classes? The elements inside may or may not be pointers and, if they are pointers, I would like to be able, when I delete my List, to specify whether I want to delete the elements inside or just the Elem wrappers around them.
Smart pointers could be an answer, but that would mean that I can't have a List<bubuType*>, but just List<smart_pointer_to_bubuType>. This could be ok, but again: declaring a List<bubuType*> would cause no error or warning and in some cases the smart pointers would cause some problems in the implementation: for example, I might want to declare a List<PSTR> for some WinAPI returns. I think getting those PSTR inside smart pointers would be an ugly job. Thus, the solution I'm looking for I think should be somehow related to the deallocation system of the List template.
Any ideas?
Without even looking at your code, I say: scrap it!
C++ has a list class template that's about as efficient as it gets, well-known to all C++ programmers, and comes bug-free with your compiler.
Learn to use the STL.1 Coming from other OO languages, the STL might seem strange, but there's an underlying reason for its strangeness, an alien beauty combining abstraction and performance - something considered impossible before Stepanov came and thought up the STL.
Rest assured that you are not the only one struggling with understanding the STL. When it came upon us, we all struggled to grasp its concepts, to learn its particularities, to understand how it ticks. The STL is a strange beast, but then it manages to combine two goals everybody thought could never be combined, so it's allowed to seem unfamiliar at first.
I bet writing your own linked list class used to be the second most popular indoor sport of C++ programmers - right after writing your own string class. Those of us who had been programming C++ 15 years ago nowadays enjoy ripping out those bug-ridden, inefficient, strange, and unknown string, list, and dictionary classes rotting in old code, and replacing it with something that is very efficient, well-known, and bug-free. Starting your own list class (other than for educational purposes) has to be one of the worst heresies.
If you program in C++, get used to one of the mightiest tools in its box as soon as possible.
1Note that the term "STL" names that part of the C++ standard library that stems from Stepanov's library (plus things like std::string which got an STL interface attached as an afterthought), not the whole standard library.
The best answer is that you must think on the lifetime of each one of the objects, and the responsibility of managing that lifetime.
In particular, in a relation from people and the sites they have visited, most probably neither of them should be naturally made responsible for the lifetime of the others: people can live independently from the sites that they have visited, and places exists regardless of whether they have been visited. This seems to hint that the lifetime of both people and sites is unrelated to the others, and that the pointers held are not related to resource management, but are rather references (not in the C++ sense).
Once you know who is responsible for managing the resource, that should be the code that should delete (or better hold the resource in a container or suitable smart pointer if it needs to be dynamically allocated), and you must ensure that the deletion does not happen before the other objects that refer to the same elements finish with them.
If at the end of the day, in your design ownership is not clear, you can fall back to using shared_ptr (either boost or std) being careful not to create circular dependencies that would produce memory leaks. Again to use the shared_ptrs correctly you have to go back and think, think on the lifetime of the objects...
Always, always use smart pointers if you are responsible for deallocating that memory. Do not ever use raw pointers unless you know that you're not responsible for deleting that memory. For WinAPI returns, wrap them into smart pointers. Of course, a list of raw pointers is not an error, because you may wish to have a list of objects whose memory you do not own. But avoiding smart pointers is most assuredly not a solution to any problem, because they're a completely essential tool.
And just use the Standard list. That's what it's for.
In the lines:
// make some links between them here:
psn1->placesVisited.Add(plc1, plc2);
psn2->placesVisited.Add(plc2, plc3);
// add the links to the places as well
plc1->peopleThatVisited.Add(psn1);
plc2->peopleThatVisited.Add(psn1, psn2);
plc3->peopleThatVisited.Add(plc3);
You have instances on the heap that contain pointers to each others. Not only one, but adding the same Place pointer to more than one person will also cause the problem (deleting more than one time the same object in memory).
Telling you to learn STL or to use shared_ptr (Boost) can be a good advice, however, as David Rodríguez said, you need to think of the lifetime of the objects. In other words, you need to redesign this scenario so that the objects do not contain pointers to each other.
Example: Is it really necessary to use pointers? - in this case, and if you require STL lists or vectors, you need to use shared_ptr, but again, if the objects make reference to each other, not even the best shared_ptr implementation will make it.
If this relationship between places and persons is required, design a class or use a container that will carry the references to each other instead of having the persons and places point at each other. Like a many-to-many table in a RDBMS. Then you will have a class/container that will take care of deleting the pointers at the end of the process. This way, no relations between Places and Persons will exist, only in the container.
Regards, J. Rivero
Without looking the exact code of the Add function, and the destructor of your list, it's hard to pin point the problem.
However, as said in the comments, the main problem with this code is that you don't use std::list or std::vector. There are proven efficient implementations, which fit what you need.
First of all, I would certainly use the STL (standard template library), but, I see that you are learning C++, so as an exercise it can be nice to write such a thing as a List template.
First of all, you should never expose data members (e.g. placeVisited and peopleThatVisited). This is a golden rule in object oriented programming. You should use getter and setter methods for that.
Regarding the problem around double deletion: the only solution is having a wrapper class around your pointers, that keeps track of outstanding references. Have a look at the boost::shared_ptr. (Boost is another magnificent well-crafted C++ library).
The program crashes because delete deallocates the memory of the pointer it is given it isn't removing the items from you list. You have the same pointer in at least two lists, so delete is getting called on the same block of memory multiple times this causes the crash.
First, smart pointers are not the answer here. All they will do is
guarantee that the objects never get deleted (since a double linked list
contains cycles, by definition).
Second, there's no way you can pass an argument to the destructor
telling it to delete contained pointers: this would have to be done
either via the list's type, one of its template arguments, partial
specialization or an argument to the constructor. (The latter would
probably require partial specialization as well, to avoid trying to
delete a non-pointer.)
Finally, the way to not delete an object twice is to not call delete on
it twice. I'm not quite sure what you thing is happening in your
destructor, but you never change cursor, so every time through, you're
deleting the same two elements. You probably need something more along
the lines of:
while ( cursor not at end ) {
Elem* next = cursor->next;
delete cursor;
cursor = next;
}
--
James Kanze
And you could easily implement [] around a normal list:
template <class Type>
class mystdlist : public std::list<Type> {
public:
Type& operator[](int index) {
list<Type>::iterator iter = this.begin();
for ( int i = 0; i < index; i++ ) {
iter++;
}
return *iter;
}
};
Why you would want to do this is strange, IMHO. If you want O(1) access, use a vector.

Know what references an object

I have an object which implements reference counting mechanism. If the number of references to it becomes zero, the object is deleted.
I found that my object is never deleted, even when I am done with it. This is leading to memory overuse. All I have is the number of references to the object and I want to know the places which reference it so that I can write appropriate cleanup code.
Is there some way to accomplish this without having to grep in the source files? (That would be very cumbersome.)
A huge part of getting reference counting (refcounting) done correctly in C++ is to use Resource Allocation Is Initialization so it's much harder to accidentally leak references. However, this doesn't solve everything with refcounts.
That said, you can implement a debug feature in your refcounting which tracks what is holding references. You can then analyze this information when necessary, and remove it from release builds. (Use a configuration macro similar in purpose to how DEBUG macros are used.)
Exactly how you should implement it is going to depend on all your requirements, but there are two main ways to do this (with a brief overview of differences):
store the information on the referenced object itself
accessible from your debugger
easier to implement
output to a special trace file every time a reference is acquired or released
still available after the program exits (even abnormally)
possible to use while the program is running, without running in your debugger
can be used even in special release builds and sent back to you for analysis
The basic problem, of knowing what is referencing a given object, is hard to solve in general, and will require some work. Compare: can you tell me every person and business that knows your postal address or phone number?
One known weakness of reference counting is that it does not work when there are cyclic references, i.e. (in the simplest case) when one object has a reference to another object which in turn has a reference to the former object. This sounds like a non-issue, but in data structures such as binary trees with back-references to parent nodes, there you are.
If you don't explicitly provide for a list of "reverse" references in the referenced (un-freed) object, I don't see a way to figure out who is referencing it.
In the following suggestions, I assume that you don't want to modify your source, or if so, just a little.
You could of course walk the whole heap / freestore and search for the memory address of your un-freed object, but if its address turns up, it's not guaranteed to actually be a memory address reference; it could just as well be any random floating point number, of anything else. However, if the found value lies inside a block a memory that your application allocated for an object, chances improve a little that it's indeed a pointer to another object.
One possible improvement over this approach would be to modify the memory allocator you use -- e.g. your global operator new -- so that it keeps a list of all allocated memory blocks and their sizes. (In a complete implementation of this, operator delete would have remove the list entry for the freed block of memory.) Now, at the end of your program, you have a clue where to search for the un-freed object's memory address, since you have a list of memory blocks that your program actually used.
The above suggestions don't sound very reliable to me, to be honest; but maybe defining a custom global operator new and operator delete that does some logging / tracing goes in the right direction to solve your problem.
I am assuming you have some class with say addRef() and release() member functions, and you call these when you need to increase and decrease the reference count on each instance, and that the instances that cause problems are on the heap and referred to with raw pointers. The simplest fix may be to replace all pointers to the controlled object with boost::shared_ptr. This is surprisingly easy to do and should enable you to dispense with your own reference counting - you can just make those functions I mentioned do nothing. The main change required in your code is in the signatures of functions that pass or return your pointers. Other places to change are in initializer lists (if you initialize pointers to null) and if()-statements (if you compare pointers with null). The compiler will find all such places after you change the declarations of the pointers.
If you do not want to use the shared_ptr - maybe you want to keep the reference count intrinsic to the class - you can craft your own simple smart pointer just to deal with your class. Then use it to control the lifetime of your class objects. So for example, instead of pointer assignment being done with raw pointers and you "manually" calling addRef(), you just do an assignment of your smart pointer class which includes the addRef() automatically.
I don't think it's possible to do something without code change. With code change you can for example remember the pointers of the objects which increase reference count, and then see what pointer is left and examine it in the debugger. If possible - store more verbose information, such as object name.
I have created one for my needs. You can compare your code with this one and see what's missing. It's not perfect but it should work in most of the cases.
http://sites.google.com/site/grayasm/autopointer
when I use it I do:
util::autopointer<A> aptr=new A();
I never do it like this:
A* ptr = new A();
util::autopointer<A> aptr = ptr;
and later to start fulling around with ptr; That's not allowed.
Further I am using only aptr to refer to this object.
If I am wrong I have now the chance to get corrections. :) See ya!