очистка вектора от указателей

Предположим, я определил такой класс:

 class foo {
 private: 
    std::vector< int* > v;
 public:
    ...
    void bar1()
    {
       for (int i = 0; i < 10; i++) {
         int *a = new int;
         v.push_back( a );
       }
    };

    void bar2()
    {
       std::vector< int >::iterator it = v.begin();
       for ( ; it != v.end(); it++ )  
         std::cout << (*it);
       v.clear();
    }
 };

Короче говоря, я отодвигаю некоторые указатели в векторе, позже я очищаю вектор. Вопрос в том, есть ли в этом коде утечка памяти? Я имею в виду, очищая вектор, правильно ли удаляются указатели?


person mahmood    schedule 09.10.2012    source источник
comment
Фактически вы помещаете на вектор только один указатель; цикл for в bar1 выполняет только строку new int;, поскольку в нем нет фигурных скобок, а i+++ - синтаксическая ошибка и ... ну, я думаю, это должен быть псевдокод.   -  person Frerich Raabe    schedule 09.10.2012
comment
Вам также понадобится вектор указателей int: std::vector< int* > v; вместо std::vector< int > v;   -  person juanchopanza    schedule 09.10.2012
comment
@juanchopanza: да, исправлено ...   -  person mahmood    schedule 09.10.2012


Ответы (4)


Да, в коде есть утечка памяти, если вы не удалите указатели. Если класс foo владеет указателями, он обязан их удалить. Вы должны сделать это перед очисткой вектора, иначе вы потеряете дескриптор памяти, которую необходимо освободить.

   for (auto p : v)
   {
     delete p;
   } 
   v.clear();

Вы можете полностью избежать проблемы с управлением памятью, используя std::vector подходящего умного указателя.

person juanchopanza    schedule 09.10.2012
comment
подскажите пожалуйста метод строгит (не умный птр) ?? - person mahmood; 09.10.2012
comment
@mahmood Это зависит от деталей вашего класса, но можно с уверенностью сказать, что вы должны сделать это непосредственно перед очисткой вектора. Обходите его, удаляя каждый элемент. Затем очистите его. - person juanchopanza; 09.10.2012
comment
Это должно быть std::vector< int* >::iterator? - person scohe001; 15.05.2019
comment
@ scohe001 Да, действительно, спасибо! Я преобразовал его в C ++ 11, чтобы полностью обойти проблему. - person juanchopanza; 15.05.2019

Думаю, самым коротким и понятным решением было бы:

std::vector<Object*> container = ... ;
for (Object* obj : container)
    delete obj;
container.clear();
person Tim Kuipers    schedule 01.10.2015

Нет, вы очищаете только векторную память. Выделенная память с «новым» все еще существует.

for (int i =0; i< v.size();i++)
   {
     delete (v[i]);
   } 
   v.clear();
person Community    schedule 09.10.2012
comment
используйте «удалить» на каждой итерации. После этого используйте clear, чтобы очистить вектор. e, g удалить (* это) - person ; 09.10.2012
comment
для (авто & я: v) {удалить (я); } v.clear (); правильный ли этот код? - person lsrawat; 05.08.2017

Вы можете использовать for_each:

std::vector<int*> v;

template<typename T>
struct deleter : std::unary_function<const T*, void>
{
  void operator() (const T *ptr) const
  {
    delete ptr;
  }
};

// call deleter for each element , freeing them
std::for_each (v.begin (), v.end (), deleter<int> ());
v.clear ();
person tozka    schedule 09.10.2012
comment
Мне часто хочется, чтобы что-то подобное deleter было легко доступно; Интересно, не могли бы вы реализовать это в терминах std::mem_fun_ptr or std: fun_ptr` или около того? - person Frerich Raabe; 09.10.2012