2015-04-04 3 views
-1

фрагмент кода ниже:Как избежать утечек памяти, с C++ с контейнерами STL?

//container declared 
map<string, structA*>& aMap; 

// allocation and insertion to container 
structA *item = new structA(); 
aMap["arrDevAddr"] = item; 

Однако я итерацию и освободить значение карты (указатель) в конце карты привыкания.

Теперь, из-за вышеописанного фрагмента кода, valgrind отмечает меня как «определенно просочившийся» сообщение.

Я хочу пояснить, общий принцип кодирования, чтобы избежать утечки памяти. По моему пониманию, в (C++-кодировании):

  1. Когда мы выделяем память, мы также имеем право на ее освобождение, ограниченное общим диапазоном кода.
  2. Когда мы сохраняем выделенную память в каком-либо контейнере (например, здесь карту), нам все равно нужно сохранить эти указатели (распределения), пока карта не будет использовать эти указатели.
  3. что означает, выделить >> добавить указатель на контейнер >> использование указателей на карте >> обеспечить «удаление/освобождение» структур-указателей, когда использование карты закончено, или если карта содержится в каком-либо объекте , то в «деструкторе» объекта карта должна быть повторена, а структурные указатели должны быть освобождены.

исправьте меня, если я ошибаюсь в своем понимании.

ВТОРОЙ СЛУЧАЙ:

class A{ 
... 
map<string, structA*>& aMap; 
... 
} 

сейчас в каком-то другом классе, карта вставляется со значением, как;

if(..) 
{ structA item; 
    aObj->aMap["arrDevAddr"] = &item; 
} 
... 

Теперь, в этом случае, как «элемент» является локальным для области видимости, будет карта будет содержащей «висячие ссылки»? Если нет, то как? В таком сценарии, каким должен быть способ, мы избегаем утечек памяти во время кодирования?

+4

Не управляйте памятью самостоятельно. Используйте смарт-указатель или контейнеры ptr Boost. – chris

+1

Или хранить ценности, а не указатели на другие вещи. – juanchopanza

+2

_ «Как избежать утечек памяти» _ Самый простой способ - просто не использовать 'new'! [Стандартная библиотека C++] (http://en.cppreference.com/w/cpp/memory) вооружает вас всем необходимым для этого. –

ответ

0

Вы бы избежать утечек памяти, храня зЬй :: unique_ptr, а не сырой указатель:

#include <iostream> 
#include <map> 
#include <memory> 
#include <string> 

struct structA {}; 
using structA_ptr = std::unique_ptr<structA>; 

//container declared 
std::map<std::string, structA_ptr> aMap; 


using namespace std; 

int main() 
{ 
    aMap.emplace("bob", structA_ptr { new structA {} }); 

    return 0; 
} 
+0

Это правильная идея, но я чувствовал себя вынужденным понизить вас за глобальную изменяемую переменную и ужасную избыточную непрозрачную typedef. – Puppy

+0

@Puppy Глобальный не будет протекать, когда он будет разрушен. Но это не правильная идея. –

+1

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

3

ли не delete или free вещи самостоятельно. Всегда используйте класс управления памятью - они абсолютно невосприимчивы к утечкам памяти и таким связанным проблемам, если вы не очень стараетесь делать что-то очень глупое.

В этом случае что-то вроде unique_ptr будет хорошо, или даже просто сохранить structA по значению.

+0

Также вы не представили подходящий пример обучения. Честно говоря, OP кажется вполне способным подставить шаблонный шаблон в стандартный шаблон - он просто сделал это с картой. – Scrubbins

+0

Я видел ниже, и это было совершенно правильно, и ваш пример совершенно не подходит для ученика, чтобы попытаться учиться. Или на многое другое. – Scrubbins

+0

Компилируемый пример далек от единственного релевантного критерия. Хотя, если вы собираетесь это сделать, создание хорошего, похожего на хорошую практику, хорошее начало. – Scrubbins