Effective clearing of vector memory - c++

Well I am creating a vector like this
vector<Member*> emp;
Then I am creating heap objects of the member class like this
Member* memObj = new Member();
Then using push_back like this
emp.push_back(memObj);
Well after using all my functions do I have to clear the memory by iterating like this ?
for( vector<Member*>::iterator iter = emp.begin();
iter != emp.end(); )
{
Member* mem = *iter;
iter = emp.erase (iter);
delete mem;
//iter++;
}
Is there any effective way other than iterating through each value? clear function calls the destructor only and it clears the values but does not free the memory..I wish to achieve polymorphism here...I am new in C++ ....please help..Thanks in advance.. :) I am not using C++11

If you are able to use a C++11 compiler, you can use one of the smart pointers.
std::unique_ptr
std::vector<std::unique_ptr<Member>> emp;
or
std::shared_ptr
std::vector<std::shared_ptr<Member>> emp;
EDIT
If you are not able to use a C++11 compiler, VS 2005 is definitely too old to support C++11, you will have to delete the objects manually, like you have shown.
However, I would add a helper class to help with deleteing the Member objects.
struct MemberDeleteHelper
{
MemberDeleteHelper(std::vector<Member*> emp) : emp_(emp);
~MemberDeleteHelper()
{
for( vector<Member*>::iterator iter = emp.begin();
iter != emp.end(); ++iter )
{
delete *iter;
}
}
std::vector<Member*>& emp_;
};
and use it as:
vector<Member*> emp;
MemberDeleteHelper deleteHelper(emp);
With this in place, the elements of emp will be deleted no matter how you return from the function. If an exception gets thrown from a nested function call, the stack will be unrolled and the elements of emp will still be deleted.
EDIT 2
Do not use auto_ptr objects in std::vector. The pitfalls of using auto_ptr in STL containers are discussed at http://www.devx.com/tips/Tip/13606 (Thanks are due to #pstrjds for the link).

Unless your intent is to added instances of types derived from Member to the vector, there's no need for vector<Member*>, just use vector<Member>.
If you actually need dynamic allocation, use vector<unique_ptr<Member>>. The smart pointer will automatically delete the instances when you clear() the vector. If this is the case, don't forget that Member needs a virtual destructor.
Similar options for pre-C++11 compilers are std::vector<std::tr1::shared_ptr<Member>> or boost::ptr_vector<Member>.
Finally, your current code has a bug. vector::erase returns a pointer to the next element, so by manually incrementing the iterator within the loop, you're skipping every other element. And I don't understand why you're going through the trouble of storing the pointer in a temporary variable. Your loop should be
for( vector<Member*>::iterator iter = emp.begin(); iter != emp.end(); )
{
delete *iter;
iter = emp.erase(iter);
}
or just delete all the elements first and then clear the vector
for( vector<Member*>::iterator iter = emp.begin(); iter != emp.end(); ++iter)
{
delete *iter;
}
emp.clear();

Related

iterating on a list of vectors of some class (C++)

Can anyone help me with why this code give me a segmentation fault on the inner loop?
I am trying to iterate on a list of vectors of some class block.
class chain
{
list<vector<Block*>* >* _blockChain;
}
Chain* someChain = new Chain();
for(list<vector<Block*>*>::iterator listIter = someChain->getChain()->end() ;
listIter != someChain->getChain()->begin(); listIter--)
{
for(vector<Block*>::iterator it = (*listIter)->begin();
it != (*listIter)->end() ; it++)
{
//do something
}
}
If you want to iterate through the list in reverse, use a reverse_iterator:
for(list<vector<Block*>*>::reverse_iterator listIter = someChain->getChain()->rbegin();
listIter != someChain->getChain()->rend(); ++listIter)
With a recent compiler you can condense that down a bit:
for (auto listIter = someChain->getChain()->rbegin();
listIter != someChain->getChain()->rend(); ++listIter)
That said, I agree with #Mike Seymour: you are using way too many pointers. For one really obvious example, there's almost never a reason to use a pointer to a vector (because a vector is itself little more than a wrapper around a pointer to data, with a little extra data for book-keeping about how much data is in the vector).
The first time you try to access listIter it is pointing to end() which is not to be dereferenced. In the inner loop you dereference listIter and try to use it.
From http://en.cppreference.com/w/cpp/container/vector/end
This element acts as a placeholder; attempting to access it results in undefined behavior.
I think you face a crash in List::end() and List::begin(). It's because you has not initialized your List anywhere in your code (at least I don't see in your given code). you need:
class Chain{
Chain()
{
_blockChain = new list<vector<int*>* >;
// initializing Vector and so on
}
};
Although this is not all of your problems.

Is this a valid way of removing items from of std::vector?

Here's my code for updating a list of items in a vector and removing some of them:
std::vector<Particle*> particles;
...
int i = 0;
while ( i < particles.size() ) {
bool shouldRemove = particles[ i ]->update();
if ( shouldRemove ) {
delete particles[ i ];
particles[ i ] = particles.back();
particles.pop_back();
} else {
i++;
}
}
When I find an item that should be removed, I replace it with the last item from the vector to avoid potentially copying the rest of the backing array multiple times. Yes, I know it is premature optimization...
Is this a valid way of removing items from the vector? I get some occasional (!) crashes somewhere around this area but can't track them down precisely (LLDB fails to show me the line), so I would like to make sure this part is OK. Or is it... ?
UPDATE: I found the bug and indeed it was in another part of my code.
Yes, this is a valid way. But if it is not a performance bottleneck in your program then it's better to use smart pointers to manage the lifetime of Particle objects.
Take a look at std::remove_if.
Also, might be good to use a shared pointer as it may make life easier :-)
typedef std::shared_ptr< Particle > ParticlePtr;
auto newend = std::remove_if( particles.begin(), particles.end(), [](ParticlePtr p) {return p->update();} );
particles.erase( newend, particles.end() );
You are iterating over an STL vector, so use iterators, it's what they're for.
std::vector<Particle*>::iterator particle = particles.begin();
while ( particle != particles.end() ) {
bool shouldRemove = particle->update();
if ( shouldRemove ) {
particle = particles.remove(particle); //remove returns the new next particle
} else {
++particle;
}
}
Or, even better, use smart pointers and the erase/remove idiom. Remove_if itself does as you describe, moving old members to the back of the vector and returning an iterator pointing to the first non-valid member. Passing this and the vector's end() to erase allows erase to erase all the old members as they are in a contiguous block. In your scenario, you would have to delete each before calling erase:
auto deleteBegin = std::remove_if(
particles.begin(), particles.end(),
[](Particle* part){ return part->update();}));
for(auto deleteIt = deleteBegin; deleteIt != particles.end(); ++deleteIt)
delete *deleteIt;
std::erase(deleteBegin, particles.end());
Or pre C++11:
bool ShouldDelete(Particle* part) {
return part->update();
}
typedef vector<Particle*> ParticlesPtrVec;
ParticlesPtrVec::iterator deleteBegin = std::remove_if(
particles.begin(), particles.end(), ShouldDelete);
for(ParticlesPtrVec::iterator deleteIt = deleteBegin;
deleteIt != particles.end(); ++deleteIt)
delete *deleteIt;
std::erase(deleteBegin, particles.end());
Then test the whole code for performance and optimise wherever the actual bottlenecks are.
I don't see any direct issue in the code. You are probably having some issues with the actual pointers inside the vector.
Try running valgrind on your code to detect any hidden memory access problems, or switch to smart pointers.

How to properly delete pointer from a std::list?

I'm creating an object via new, then later adding the pointer to an std::list once the object is set up.
What is the correct way of deleting a pointer and erasing the data from the list without causing memory leaks?
Instead of manual loop to search the element, I would rather use std::find_if
auto it = std::find_if(lst.begin(),
lst.end(),
[&val](datalist const &d) { return d.index == val; });
if ( it != lst.end() )
{
delete *it;
lst.erase(it);
}
That is not to say that you're doing it incorrectly.
However, your code will improve if you consider using some form of smart points, such as std::unique_ptr, std::shared_ptr, or boost's smart pointers, then you don't have to manage memory yourself.
If you change your std::list to hold datalist instances instead of datalist* pointers, then you don't have to delete the datalist instances manually anymore. When you remove an element from a std::list (or any other STL container, for that matter), the element's data is freed automatically for you. If the element is a class/struct with a destructor defined, the destructor will be called.
Try this:
std::list<datalist> m_DataList;
.
datalist AR; // <-- local variable on the stack, freed when out of scope
AR.index = ...;
AR.number = ...;
mylist.push_back(AR); // <-- pushes a copy-constructed instance of the variable
.
std::list<datalist>::iterator Iter1 = m_DataList.begin();
while(Iter1 != m_DataList.end())
{
if (Iter1->index == m_SomeVar)
{
m_DataList.erase(Iter1); // <-- copied datalist instance is freed automatically
break;
}
++Iter1;
}

Vector Iterators Casting

Hey, In C++, I have a vector of type:
vector<BaseClass*> myVector;
In which, I insert (push_back) pointers of derived classes into it.
Now, I want to pop back its elements so I do this:
vector<ADlgcDev*>::iterator iter;
for (iter = myVector.rbegin(); iter != myVector.rend(); iter++)
{
// but before I pop it, I need to shutdown it down
// so I cast this
// but this way, I'm unable to call the function
(DerivedClass*(*iter))->Shutdown();
myVector.pop_back();
}
but as mention in the comments before I pop it, I need to call its Shutdown() method and the cast is not working properly too. Any resolutions? or is impossible?
while (!myVector.empty())
{
((DerivedClass*)(myVector.back()))->Shutdown();
myVector.pop_back();
}
Notes:
You should probably use dynamic_cast instead of the hard cast. (If it's sure that there are only DerivedClass objects in the vector, why isn't it std::vector<DerivedClass>?)
You should probably not have to cast at all, since Shutdown() should be declared in the base class.
You should probably delete the objects, too, before you pop them off the vector. (But that might not be so.)
You should probably use a smart pointer which calls Shutdown() (and delete, probably).
Edit: Using std::vector<T>::clear(), as shown by markh44 is probably better than the pop_back().
Could you make Shutdown a virtual function in BaseClass? Then you wouldn't need a cast.
Also you'll probably have trouble removing items from a vector while iterating. I'd do it like this:
vector<BaseClass*>::iterator iter;
for (iter = myVector.rbegin(); iter != myVector.rend(); iter++)
{
(*iter)->Shutdown();
}
myVector.clear();
Edit: and another thing, ++iter is generally preferred over iter++.
The constructor casting doesn't work for pointers. Use static_cast if you're sure or dynamic_cast and check.
If Shutdown() is a virtual method of the Base class i.e. BaseClass::ShutDown() you should directly call iter->ShutDown();
Otherwise if the method isn't virtual you should use dynamic_cast.
vector<ADlgcDev*>::iterator iter;
for (iter = myVector.rbegin(); iter != myVector.end(); iter++)
{
DerivedClassA* a = dynamic_cast<DerivedClassA*>( *iter ) ;
if ( a ) a->ShutDownA();
else
{
DerivedClassB* b = dynamic_cast<DerivedClassB*>(*iter);
if ( b ) b->ShutDownB();
// ... repeat for every class in hierarchy that might be in the vector.
}
myVector.pop_back();
}
Anyway you're probably leaking memory, unless ShutDown() deletes the object from itself (which is generally a bad idea ) or you're keeping duplicated pointers and deleting them elsewhere, which is another risky idea.

Cleaning up an STL list/vector of pointers

What is the shortest chunk of C++ you can come up with to safely clean up a std::vector or std::list of pointers? (assuming you have to call delete on the pointers?)
list<Foo*> foo_list;
I'd rather not use Boost or wrap my pointers with smart pointers.
For std::list<T*> use:
while(!foo.empty()) delete foo.front(), foo.pop_front();
For std::vector<T*> use:
while(!bar.empty()) delete bar.back(), bar.pop_back();
Not sure why i took front instead of back for std::list above. I guess it's the feeling that it's faster. But actually both are constant time :). Anyway wrap it into a function and have fun:
template<typename Container>
void delete_them(Container& c) { while(!c.empty()) delete c.back(), c.pop_back(); }
Since we are throwing down the gauntlet here... "Shortest chunk of C++"
static bool deleteAll( Foo * theElement ) { delete theElement; return true; }
foo_list . remove_if ( deleteAll );
I think we can trust the folks who came up with STL to have efficient algorithms. Why reinvent the wheel?
for(list<Foo*>::const_iterator it = foo_list.begin(); it != foo_list.end(); ++it)
{
delete *it;
}
foo_list.clear();
If you allow C++11, you can do a very short version of Douglas Leeder's answer:
for(auto &it:foo_list) delete it; foo_list.clear();
It's really dangerous to rely on code outside of the container to delete your pointers. What happens when the container is destroyed due to a thrown exception, for example?
I know you said you don't like boost, but please consider the boost pointer containers.
template< typename T >
struct delete_ptr : public std::unary_function<T,bool>
{
bool operator()(T*pT) const { delete pT; return true; }
};
std::for_each(foo_list.begin(), foo_list.end(), delete_ptr<Foo>());
I'm not sure that the functor approach wins for brevity here.
for( list<Foo*>::iterator i = foo_list.begin(); i != foo_list.end(); ++i )
delete *i;
I'd usually advise against this, though. Wrapping the pointers in smart pointers or using a specialist pointer container is, in general, going to be more robust. There are lots of ways that items can be removed from a list ( various flavours of erase, clear, destruction of the list, assignment via an iterator into the list, etc. ). Can you guarantee to catch them all?
The following hack deletes the pointers when your list goes out of scope using RAII or if you call list::clear().
template <typename T>
class Deleter {
public:
Deleter(T* pointer) : pointer_(pointer) { }
Deleter(const Deleter& deleter) {
Deleter* d = const_cast<Deleter*>(&deleter);
pointer_ = d->pointer_;
d->pointer_ = 0;
}
~Deleter() { delete pointer_; }
T* pointer_;
};
Example:
std::list<Deleter<Foo> > foo_list;
foo_list.push_back(new Foo());
foo_list.clear();
At least for a list, iterating and deleting, then calling clear at the end is a bit inneficient since it involves traversing the list twice, when you really only have to do it once. Here is a little better way:
for (list<Foo*>::iterator i = foo_list.begin(), e = foo_list.end(); i != e; )
{
list<Foo*>::iterator tmp(i++);
delete *tmp;
foo_list.erase(tmp);
}
That said, your compiler may be smart enough to loop combine the two anyways, depending on how list::clear is implemented.
Actually, I believe the STD library provides a direct method of managing memory in the form of the allocator class
You can extend the basic allocator's deallocate() method to automatically delete the members of any container.
I /think/ this is the type of thing it's intended for.
for(list<Foo*>::const_iterator it = foo_list.begin(); it != foo_list.end(); it++)
{
delete *it;
}
foo_list.clear();
There's a small reason why you would not want to do this - you're effectively iterating over the list twice.
std::list<>::clear is linear in complexity; it removes and destroys one element at a time within a loop.
Taking the above into consideration the simplest to read solution in my opinion is:
while(!foo_list.empty())
{
delete foo_list.front();
foo_list.pop_front();
}
Since C++11:
std::vector<Type*> v;
...
std::for_each(v.begin(), v.end(), std::default_delete<Type>());
Or, if you are writing templated code and want to avoid specifying a concrete type:
std::for_each(v.begin(), v.end(),
std::default_delete<std::remove_pointer<decltype(v)::value_type>::type>());
Which (since C++14) can be shortened as:
std::for_each(v.begin(), v.end(),
std::default_delete<std::remove_pointer_t<decltype(v)::value_type>>());
void remove(Foo* foo) { delete foo; }
....
for_each( foo_list.begin(), foo_list.end(), remove );
for (list<Foo*>::const_iterator i = foo_list.begin(), e = foo_list.end(); i != e; ++i)
delete *i;
foo_list.clear();
This seems cleanest imo, but your c++ version must support this type of iteration (I believe anything including or ahead of c++0x will work):
for (Object *i : container) delete i;
container.clear();