2012-06-01 4 views
1

Можно создать дубликат:
how to properly delete pointer?лучший способ удалить векторный указатель?

я использую std::vector поставить группу объектов в ней для дальнейшего использования, я использую DETAIL* pPtr = new DETAIL создать указатель, а затем вставить его в вектор.

структура детальности

struct DETAIL { 
    int nRef; 
    short sRandom; 
}; 

Это лучший способ удалить и удалить указатель в векторе, не оставляя места для утечек памяти?

while(Iter1 != m_Detail.end()) 
{ 
    if((*Iter1)->nRef == m_SomeVar)  
    { 
     delete *Iter1; 
     m_Detail.erase(Iter1); 
     break; 
    } 

    Iter1++; 
} 
+3

Почти всегда неправильно указывать указатель на вектор и/или вектор типов указателей. (Почти всегда. Не делай этого. –

+1

не задал этот вопрос пару часов назад? http://stackoverflow.com/questions/10854274/how-to-properly-delete-pointer – PermanentGuest

+0

Если ваш вектор содержит исходные указатели, вы можете абсолютно ничего сделать, чтобы защитить его, если вектор, например, уничтожен исключением. Возможность утечек всегда есть. –

ответ

9

Не помещайте сырые указатели в vector, вместо того, чтобы использовать смарт-указатели, такие как std::shared_ptr. Тогда нет необходимости в delete, просто erase указатель от vector, и указанный объект будет автоматически удален.

-2

Я не знаю, полностью ли я это понял, но вы пытались использовать макрос ZeroMemory?

+2

Я не понимаю этого ответа. –

+0

ZeroMemory в макросе MSVC используется только для установки блока смежной памяти на 0. Это НЕ МОЖЕТ использоваться с контейнерами std. – Plexico

0

Мое предложение было бы использовать std :: shared_ptr удалить общий указатель из вектора, используя стирание, и позволить ему позаботиться об освобождении. Однако нет ничего плохого в том, что вы делаете, но стирание не приводит к тому, что вектор освобождает пространство, которое он выделил для удержания указателя. Вы можете использовать shrik_to_fit, чтобы удалить выделенное пространство.

0

я использую DETAIL* pPtr = new DETAIL создать указатель

Это ваша первая ошибка, вы приобретя ресурс (память от FreeStore и объекта, построенного в этой памяти) и не инициализирует объект, возьмут на себя ответственность и гарантируют освобождение ресурсов, которые вы приобрели. Идиома для решения этой первой ошибки называется Resource Acquisition Is Initialization.

Это должно быть что-то вроде:

std::shared_ptr<DETAIL> pPtr(new DETAIL); 

Или еще лучше:

std::shared_ptr<DETAIL> pPtr = std::make_shared<DETAIL>(); 

Или в C++ 03 заменить std::shared_ptr с boost::shared_ptrboost::make_shared)

Следующая ошибка является delete *Iter1;, потому что почти любой код, который использует delete вне деструктора, неверен (и все код, который использует delete вне деструктора и сопровождается вопросом о том, как избежать утечек памяти, определенно неправильно.) Если вы используете идиому RAII, вам не нужно использовать delete, потому что это происходит автоматически в нужное время.

Кроме того, почему ваш класс называется DETAIL? Что случилось с Detail?

0

Мне не нравится отвечать как «никогда не делаю», поэтому я отвечу, но дает вам некоторые трюки, чтобы обойти риск освобождения вектора, не освобождая контент.

, если я хорошо понимаю, у вас есть вектор ПОДРОБНЫХ указателей:

std::vector<DETAIL*> details; 

Так что вы хотите способ удалить и удалить все острые предметы, которые относятся к определенному m_SomeVar: (сейчас давайте представим, что это бесплатно функция)

void free_references(int reference, std::vector<DETAIL*> & vector) 
{ 
    std::vector<DETAIL*>::iterator it = vector.begin(); 

    while (it != vector.end()) 
    { 
     if ((*it)->nRef == reference) 
     { 
      delete *it; 
      // erase() makes the original 'it' in an unknown state which can't be used 
      // erase will return a valid iterator which is, in this case, the following element 
      it = vector.erase(it); 
     } 
     else 
     { 
      ++it; 
     } 
    } 
} 

Как я понимаю, в вашем коде вектор является членом класса. Это хорошая причина, что вы сможете удалить все в деструкторе.

Однако я бы использовал std::unique_ptr здесь, чтобы «дать» право собственности на указатель на контейнер unique_ptr внутри вектора. И когда свободная векторная память свободна, умная точка std::unique_ptr удостоверяется, что выделенный выделенный объект свободен.

Смежные вопросы