I have a class. Let's call it House. Houses of various properties are contained in a registry. Let's call this house registry. Within this class, I want to add a vector containing pointers to different houses sorted in different ways(perhaps by name and number). Within this class, I have a function that creates new House objects and inserts them in the respective order. In doing so I'm leaving memory leaks as the program may terminate in a myriad of ways but doesn't free up memory stored in the vector. I know I can use smart pointers. But how do I implement them in the right way? I'm intentionally leaving out the destructor as its implementation is fairly obvious. But this question is specifically about smart pointers. A great answer would preferably include their implementation with comparators.
class HouseRegistry{
struct House{
....
}
private:
vector<House*>HousesbyName;
vector<House*>HousesbyNumber
bool newHouse(...){
House *somehouse = new House;
....
HousesbyName.insert(inserter,somehouse);
HousesbyNumber.insert(inserter2,somehouse);
return true;
}
}
I know a solution might look something like
class HouseRegistry{
struct House{
....
}
private:
vector<shared_ptr<House>>HousesbyName;
vector<shared_ptr<House>>HousesbyNumber
bool newHouse(...){
auto somehouse = make_shared<House>();
....
HousesbyName.insert(inserter,somehouse);
HousesbyNumber.insert(inserter2,somehouse);
return true;
}
}
But it breaks for functions like Binary Search when the comparator function uses two House pointers as arguments. What would a subsequent comparator function look like in this case if looking for any preexisting occurrence of a house?
#include <vector>
#include <memory>
std::vector<std::shared_ptr<House>> HousesbyName;
std::vector<std::shared_ptr<House>> HousesbyNumber
auto somehouse = std::make_shared<House>();
...
HousesbyName.insert(inserter, somehouse);
HousesbyNumber.insert(inserter2, somehouse);
...
How do I ensured all pointers are freed?
In general: By always freeing every dynamic allocation after you no longer need them.
The general answer is simple, and following it isn't easy. There are ways to make it easier in different cases. The easiest way is to not use dynamic allocation manually at all in the first place. Your example doesn't necessarily demonstrate a need for it. You could use std::vector<House> to store the objects. Alternatively, your use cases seems appropriate for a multi-index container. The standard doesn't provide a multi-index container template, but Boost does.
But in case where you do need dynamic allocation, a simple way to avoid leaks is to never use new, std::malloc etc. and instead use containers or std::make_unique or std::make_shared and never call std::unique_ptr::release.
Related
I have a question about using multiple pointers to an object.
I have a pointer in a vector and another one in a map.
The map uses the vector to index the object. Example code:
class Thing
{
public:
int x = 1;
};
Thing obj_Thing;
std::vector<Thing*> v_Things;
v_Things.push_back(&obj_Thing);
std::map<int, Thing*> m_ThingMap;
m_ThingsMap[v_Things[0]->x] = v_Things[0]; // crucial part
is it good practice to assign pointers to each other like this?
Should the vector and/or map hold addresses instead? Or should I be using a pointer to pointer for the map?
It all depends on what you want to do.
However, your approach can get really hairy when your project grows, and especially when others contribute to it.
To start with, this:
m_ThingsMap[v_Things[0]->x] = v_Things(0);
should be:
m_ThingsMap[v_Things[0]->x] = v_Things[0];
Moreover, storing raw pointers in a std::vector is possible, but needs special care, since you may end up with dangling pointers, if the object that a pointer points to gets deallocated too soon.
For that I suggest you to use std::weak_ptr, like this:
std::vector<std::weak_ptr<Thing>> v_Things;
in case you decide to stick with that approach (I mean if the pointer points to an object that is pointer-shared from another pointer).
If I were you, I would redesign my approach, since your code is not clean enough, let alone your logic; it takes one moment or two for someone to understand what is going on with all the pointers and shared places.
I am relatively new to pointers and have written this merge function. Is this effective use of pointers? and secondly the *two variable, it should not be deleted when they are merged right? that would be the client´s task, not the implementer?
VectorPQueue *VectorPQueue::merge(VectorPQueue *one, VectorPQueue *two) {
int twoSize = two->size();
if (one->size() != 0) {
for (int i = 0; i < twoSize;i++)
{
one->enqueue(two->extractMin());
}
}
return one;
}
The swap function is called like this
one->merge(one, two);
Passing it the these two objects to merge
PQueue *one = PQueue::createPQueue(PQueue::UnsortedVector);
PQueue *two = PQueue::createPQueue(PQueue::UnsortedVector);
In your case pointers are completely unnecessary. You can simply use references.
It is also unnecessary to pass in the argument on which the member function is called. You can get the object on which a member function is called with the this pointer.
/// Merge this with other.
void VectorPQueue::merge(VectorPQueue& other) {
// impl
}
In general: Implementing containers with inheritance is not really the preferred style. Have a look at the standard library and how it implements abstractions over sequences (iterators).
At first sight, I cannot see any pointer-related problems. Although I'd prefer to use references instead, and make merge a member function of VectorPQueue so I don't have to pass the first argument (as others already pointed out). One more thing which confuses me is the check for one->size() != 0 - what would be the problem if one is empty? The code below would still correctly insert two into one, as it depends only on two's size.
Regarding deletion of two:
that would be the client´s task, not the implementer
Well, it's up to you how you want do design your interface. But since the function only adds two's elements to one, I'd say it should not delete it. Btw, I think a better name for this method would be addAllFrom() or something like this.
Regarding pointers in general:
I strongly suggest you take a look into smart pointers. These are a common technique in C++ to reduce memory management effort. Using bare pointers and managing them manually via new/delete is very error-prone, hard to make strongly exception-safe, will almost guarantee you memory leaks etc. Smart pointers on the other hand automatically delete their contained pointers as soon as they are not needed any more. For illustrative purposes, the C++ std lib has auto_ptr (unique_ptr and shared_ptr if your compiler supports C++ 11). It's used like this:
{ // Beginning of scope
std::auto_ptr<PQueue> one(PQueue::createPQueue(PQueue::UnsortedVector));
// Do some work with one...:
one->someFunction();
// ...
} // End of scope - one will automatically be deleted
My personal rules of thumb: Only use pointers wrapped in smart pointers. Only use heap allocated objects at all, if:
they have to live longer than the scope in which they are created, and a copy would be too expensive (C++ 11 luckily has move semantics, which eliminate a lot of such cases)
I have to call virtual functions on them
In all other cases, I try to use stack allocated objects and STL containers as much as possible.
All this might seem a lot at first if you're starting with C++, and it's totally ok (maybe even necessary) to try to fully understand pointers before you venture into smart pointers etc.. but it saves a lot of time spend debugging later on. I'd also recommend reading a few books on C++ - I was actually thinking I understood most of C++, until I read my first book :)
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.
I'd like to use a std::vector to control a given piece of memory. First of all I'm pretty sure this isn't good practice, but curiosity has the better of me and I'd like to know how to do this anyway.
The problem I have is a method like this:
vector<float> getRow(unsigned long rowIndex)
{
float* row = _m->getRow(rowIndex); // row is now a piece of memory (of a known size) that I control
vector<float> returnValue(row, row+_m->cols()); // construct a new vec from this data
delete [] row; // delete the original memory
return returnValue; // return the new vector
}
_m is a DLL interface class which returns an array of float which is the callers responsibility to delete. So I'd like to wrap this in a vector and return that to the user.... but this implementation allocates new memory for the vector, copies it, and then deletes the returned memory, then returns the vector.
What I'd like to do is to straight up tell the new vector that it has full control over this block of memory so when it gets deleted that memory gets cleaned up.
UPDATE: The original motivation for this (memory returned from a DLL) has been fairly firmly squashed by a number of responders :) However, I'd love to know the answer to the question anyway... Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?
The obvious answer is to use a custom allocator, however you might find that is really quite a heavyweight solution for what you need. If you want to do it, the simplest way is to take the allocator defined (as the default scond template argument to vector<>) by the implementation, copy that and make it work as required.
Another solution might be to define a template specialisation of vector, define as much of the interface as you actually need and implement the memory customisation.
Finally, how about defining your own container with a conforming STL interface, defining random access iterators etc. This might be quite easy given that underlying array will map nicely to vector<>, and pointers into it will map to iterators.
Comment on UPDATE: "Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?"
Surely the simple answer here is "No". Provided you want the result to be a vector<>, then it has to support growing as required, such as through the reserve() method, and that will not be possible for a given fixed allocation. So the real question is really: what exactly do you want to achieve? Something that can be used like vector<>, or something that really does have to in some sense be a vector, and if so, what is that sense?
Vector's default allocator doesn't provide this type of access to its internals. You could do it with your own allocator (vector's second template parameter), but that would change the type of the vector.
It would be much easier if you could write directly into the vector:
vector<float> getRow(unsigned long rowIndex) {
vector<float> row (_m->cols());
_m->getRow(rowIndex, &row[0]); // writes _m->cols() values into &row[0]
return row;
}
Note that &row[0] is a float* and it is guaranteed for vector to store items contiguously.
The most important thing to know here is that different DLL/Modules have different Heaps. This means that any memory that is allocated from a DLL needs to be deleted from that DLL (it's not just a matter of compiler version or delete vs delete[] or whatever). DO NOT PASS MEMORY MANAGEMENT RESPONSIBILITY ACROSS A DLL BOUNDARY. This includes creating a std::vector in a dll and returning it. But it also includes passing a std::vector to the DLL to be filled by the DLL; such an operation is unsafe since you don't know for sure that the std::vector will not try a resize of some kind while it is being filled with values.
There are two options:
Define your own allocator for the std::vector class that uses an allocation function that is guaranteed to reside in the DLL/Module from which the vector was created. This can easily be done with dynamic binding (that is, make the allocator class call some virtual function). Since dynamic binding will look-up in the vtable for the function call, it is guaranteed that it will fall in the code from the DLL/Module that originally created it.
Don't pass the vector object to or from the DLL. You can use, for example, a function getRowBegin() and getRowEnd() that return iterators (i.e. pointers) in the row array (if it is contiguous), and let the user std::copy that into its own, local std::vector object. You could also do it the other way around, pass the iterators begin() and end() to a function like fillRowInto(begin, end).
This problem is very real, although many people neglect it without knowing. Don't underestimate it. I have personally suffered silent bugs related to this issue and it wasn't pretty! It took me months to resolve it.
I have checked in the source code, and boost::shared_ptr and boost::shared_array use dynamic binding (first option above) to deal with this.. however, they are not guaranteed to be binary compatible. Still, this could be a slightly better option (usually binary compatibility is a much lesser problem than memory management across modules).
Your best bet is probably a std::vector<shared_ptr<MatrixCelType>>.
Lots more details in this thread.
If you're trying to change where/how the vector allocates/reallocates/deallocates memory, the allocator template parameter of the vector class is what you're looking for.
If you're simply trying to avoid the overhead of construction, copy construction, assignment, and destruction, then allow the user to instantiate the vector, then pass it to your function by reference. The user is then responsible for construction and destruction.
It sounds like what you're looking for is a form of smart pointer. One that deletes what it points to when it's destroyed. Look into the Boost libraries or roll your own in that case.
The Boost.SmartPtr library contains a whole lot of interesting classes, some of which are dedicated to handle arrays.
For example, behold scoped_array:
int main(int argc, char* argv[])
{
boost::scoped_array<float> array(_m->getRow(atoi(argv[1])));
return 0;
}
The issue, of course, is that scoped_array cannot be copied, so if you really want a std::vector<float>, #Fred Nurk's is probably the best you can get.
In the ideal case you'd want the equivalent to unique_ptr but in array form, however I don't think it's part of the standard.
I'm having some trouble to find the best way to accomplish what I have in mind due to my inexperience. I have a class where I need to a vector of objects. So my first question will be:
is there any problem having this: vector< AnyType > container* and then on the constructor initialize it with new (and deleting it on the destructor)?
Another question is: if this vector is going to store objects, shouldn't it be more like vector< AnyTipe* > so they could be dynamically created? In that case how would I return an object from a method and how to avoid memory leaks (trying to use only STL)?
Yes, you can do vector<AnyType> *container and new/delete it. Just be careful when you do subscript notation to access its elements; be sure to say (*container)[i], not container[i], or worse, *container[i], which will probably compile and lead to a crash.
When you do a vector<AnyType>, constructors/destructors are called automatically as needed. However, this approach may lead to unwanted object copying if you plan to pass objects around. Although vector<AnyType> lends itself to better syntactic sugar for the most obvious operations, I recommend vector<AnyType*> for non-primitive objects simply because it's more flexible.
is there any problem having this: vector< AnyType > *container and then on the constructor initialize it with new (and deleting it on the destructor)
No there isn't a problem. But based on that, neither is there a need to dynamically allocate the vector.
Simply make the vector a member of the class:
class foo
{
std::vector<AnyType> container;
...
}
The container will be automatically constructed/destructed along with the instance of foo. Since that was your entire description of what you wanted to do, just let the compiler do the work for you.
Don't use new and delete for anything.
Sometimes you have to, but usually you don't, so try to avoid it and see how you get on. It's hard to explain exactly how without a more concrete example, but in particular if you're doing:
SomeType *myobject = new SomeType();
... use myobject for something ...
delete myobject;
return;
Then firstly this code is leak-prone, and secondly it should be replaced with:
SomeType myobject;
... use myobject for something (replacing -> with . etc.) ...
return;
Especially don't create a vector with new - it's almost always wrong because in practice a vector almost always has one well-defined owner. That owner should have a vector variable, not a pointer-to-vector that they have to remember to delete. You wouldn't dynamically allocate an int just to be a loop counter, and you don't dynamically allocate a vector just to hold some values. In C++, all types can behave in many respects like built-in types. The issues are what lifetime you want them to have, and (sometimes) whether it's expensive to pass them by value or otherwise copy them.
shouldn't it be more like vector< AnyTipe* > so they could be dynamically created?
Only if they need to be dynamically created for some other reason, aside from just that you want to organise them in a vector. Until you hit that reason, don't look for one.
In that case how would I return an object from a method and how to avoid memory leaks (trying to use only STL)?
The standard libraries don't really provide the tools to avoid memory leaks in all common cases. If you must manage memory, I promise you that it is less effort to get hold of an implementation of shared_ptr than it is to do it right without one.