What do I need to do before deleting elements in a

2019-01-07 16:22发布

I have a vector that I fill with pointers to objects. I am trying to learn good memory management, and have a few general questions:

  1. Is it true that when I am done with the vector, I must loop through it and call delete on each pointer?
  2. Why don't I have to call delete on the vector or any other variable I declare without the new statement, but delete must be called on pointers?
  3. Does C++ handle freeing the pointers' memory for me if the vector is declared in a function which returns (causing the vector to go out of scope)?

5条回答
仙女界的扛把子
2楼-- · 2019-01-07 17:01

Is it true that when I am done with the vector I must loop through it and call delete on each pointer?

Well, you don't have to loop by hand, you can also use an algorithm:

#include <vector>
#include <algorithm>
#include <memory>

int main()
{
    std::vector<Base*> vec;
    vec.push_back(new Derived());
    vec.push_back(new Derived());
    vec.push_back(new Derived());

    // ...

    std::for_each(vec.begin(), vec.end(), std::default_delete<Base>());
}

If you don't have a C++0x compiler, you can use boost:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/construct.hpp>

std::for_each(vec.begin(), vec.end(), boost::lambda::delete_ptr());

Or you can write your own functor:

struct delete_ptr
{
    template <class T>
    void operator()(T* p)
    {
        delete p;
    }
};

std::for_each(vec.begin(), vec.end(), delete_ptr());
查看更多
闹够了就滚
3楼-- · 2019-01-07 17:02
  1. Yes
  2. Vectors are implemented using template memory allocators that take care of the memory management for you, so they are somewhat special. But as a general rule of thumb, you don't have to call delete on variables that aren't declared with the new keyword because of the difference between stack and heap allocation. If stuff is allocated on the heap, it must be deleted (freed) to prevent memory leaks.
  3. No. You explicitly have to call delete myVec[index] as you iterate over all elements.

Ex:

for(int i = 0; i < myVec.size(); ++i)
   delete myVec[i];

With that said, if you're planning on storing pointers in a vector, I strongly suggest using boost::ptr_vector which automatically takes care of the deletion.

查看更多
一纸荒年 Trace。
4楼-- · 2019-01-07 17:04

Everything you allocate with new you have to delete later on. Objects that you don't explicitly allocate with new shouldn't you delete.

If you don't want to manage the objects manually but want the vector to "own" them, it might be better to store the objects by value instead of storing pointers to them. So instead of std::vector<SomeClass*> you could use std::vector<SomeClass>.

查看更多
甜甜的少女心
5楼-- · 2019-01-07 17:04

As an alternative to boost::ptr_vector as mentioned by David Titarenco, you can easily modify std::vector to automatically free memory for containing pointers on deletion:

template<class T>
class Group : public std::vector<T>
{
public:
    virtual ~Group() {};
};

template<class T>
class Group<T *> : public std::vector<T *>
{
public:
    virtual ~Group()
    {
        std::vector<T *>::reverse_iterator it;
        for (it = this->rbegin(); it != this->rend(); ++it)
            delete *it;
    }
};

All functionality provided by std::vector is inherited so you would add items the same way:

Group<Foo *> *bar = new Group<Foo *>();
bar->push_back(new Foo());
bar->push_back(new DerivedFoo());

// Deleting the Group will free all memory allocated by contained pointers
delete bar;
查看更多
再贱就再见
6楼-- · 2019-01-07 17:11

You can also use std::unique_ptr if you have access to C++0x. It replaces the deprecated std::auto_ptr that couldn't be used in containers.

查看更多
登录 后发表回答