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

Да предположим, че съм дефинирал клас като този:

 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
можете ли да ми дадете straghit метод (не smart ptr)?? - 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
използвайте 'delete' при всяка итерация. След това използвайте clear, за да изчистите вектора. e,g изтрий (*it) - person ; 09.10.2012
comment
for (auto& i : v) { delete (i); } 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