C ++ При вставке объектов кучи в std :: map с помощью insert () и существует другой, который удаляет новый?

0

Я пытаюсь (каким-то образом) кэшировать несколько итераций на std :: map, когда мне нужно вставить несколько значений с помощью этого метода:

enum PROPERTY_TYPE
{
    TYPE_BOOLEAN,
    TYPE_INTEGER,
    TYPE_UNSIGNED,
    TYPE_FLOAT,
    TYPE_STRING
};
struct Property {
    Property(PROPERTY_TYPE type)
        : type(type), bool_val(false), integer_val(0), unsigned_val(0), float_val(0.0f), string_val("")
        {  }
    PROPERTY_TYPE       type;
    bool                bool_val;
    int                 integer_val;
    unsigned int        unsigned_val;
    float               float_val;
    std::string         string_val;
};
std::map< std::string, Property* >          _Properties;

void pushBool(std::string key, bool value)
{
    std::pair< std::map< std::string, Property* >::iterator, bool > pItr;
    pItr = _Properties.insert( std::pair< std::string, Property* >(key, new Property(TYPE_BOOLEAN)) );
    // If the value doesn't exist then it created automatically or the existion one is used.
    pItr.first->second->bool_val = value;
    pItr.first->second->integer_val = value ? 1 : 0;
    pItr.first->second->unsigned_val = value ? 1 : 0;
    pItr.first->second->float_val = value ? 1.0f : 0.0f;
    pItr.first->second->string_val = value ? "true" : "false";
}

Это самый быстрый и безопасный способ заставить его работать до сих пор. Однако меня интересует одна мелочь и функция insert(). Когда я вызываю новое свойство (TYPE_BOOLEAN), я четко создаю новое свойство(), которое никто не контролирует. И из того, что я читал, std :: map не вызывает удаление указателей при отбрасывании. И когда я использую этот метод вставки, функция insert использует существующее значение, если оно уже существует. Итак, кто удаляет это вновь созданное свойство(), если значение уже существует и оно используется вместо нового?

    pItr = _Properties.insert( std::pair< std::string, Property* >(key, new Property(TYPE_BOOLEAN)) );

Будет ли этот метод пустой тратой памяти путем введения утечек памяти?

  • 0
    Использование имени _Properties в клиентском коде C ++ запрещено .
Теги:
object
pointers
insert
map

2 ответа

2
Лучший ответ

Вы правы - std::map не покупает вопрос о том, кто удаляет любые указатели, которые он хранит, - он ожидает, что клиентский код возьмет на себя ответственность или сохранит тип, который делает это по своей сути. Самый простой и часто лучший способ сделать это - то, как вы использовали бы, если бы не видели ясную причину, в противном случае - хранить "семантический" тип значения - тот, который заботится о своей собственной жизни, и может быть копируются интуитивно, ведут себя так же, как int или другой встроенный тип в этом отношении.

В вашем случае там, по-видимому, нет причин использовать указатели вообще... просто

std::map< std::string, Property > _Properties;

Если вам все равно, вставляете ли вы новый элемент или обновляете старый:

Property& p = _Properties[key];
p.bool_val = value;
p.integer_val = ... etc

Отдельно, если идея состоит в том, что Property концептуально хранит любой из этих типов данных, вы можете найти boost::variant полезным: http://www.boost.org/doc/libs/1_55_0/doc/html/variant. HTML

  • 0
    Вы правы, я должен использовать std :: map <std :: string, Property>, но я, кажется, забыл, что я не использую вектор, который изменяет свой размер при вставке (неприятная привычка), поэтому я начал с указатели. До сих пор я никогда не использовал карты, и из того, что я прочитал, они не удаляют значения при изменении размеров, как векторы. Спасибо за помощь. Я сделаю несколько тестов и посмотрю, как это будет :)
  • 1
    @SanduLiviuCatalin Даже при использовании std :: vector я храню не указатели, а объекты, управляющие памятью при копировании / назначении / уничтожении (исключение составляет хорошо инкапсулированный контейнер)
3

Да, эта линия может вызвать утечку.

Либо хранить интеллектуальные указатели, либо проверить наличие перед вставкой. Я бы посоветовал умные указатели. unique_ptr вероятно, для указания права собственности.

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

  • 0
    Я не могу видеть, как unique_ptr может помочь здесь. Должен быть shared_ptr, я считаю.
  • 0
    @kitfisto map< string, unique_ptr<Properties>> не помогает, потому что почему?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню