std :: unordered_map как освободить структуру, созданную с помощью malloc.Требуется ли 2 запроса на карту? - PullRequest
1 голос
/ 16 апреля 2019

Кажется, что следующий блок кода работает нормально. Генерирует:

Добавьте 1000 вещей _MyMap теперь содержит [1000] вещей _MyMap free'd и стерты.размер сейчас [0]

#include <unordered_map>
#include <iostream>

typedef struct _entry
{
    int now;
} ENTRY, * PENTRY;

std::unordered_map<int, PENTRY> _MyMap;
typedef std::unordered_map<int, PENTRY>::iterator itEntry;

int Now()
{
    return 10;
}

основная функция, добавление комментариев, поскольку сайт не позволяет мне просто добавлять код

int main()
{   
    PENTRY pE = NULL;

    std::pair<itEntry, bool> r;

    printf("Add 1000 things\n");
    for (int i = 0; i < 1000; i++)
    {
        pE = (PENTRY)malloc(sizeof(ENTRY));
        pE->now = Now();

        r = _MyMap.insert(std::make_pair(i, pE));

        if (false == r.second)
        {
            printf("For some crazy reason its already there\n");
            continue;
        }
    }

    // OK, theres probably 1000 things in there now
    printf("_MyMap now holds [%u] things\n", _MyMap.size() );

    // The following seems stupid, but I don't understand how to free the memory otherwise
    for (int i = 0; i < 1000; i++)
    {
        // first query
        auto it = _MyMap.find(i);

        // if malloc failed on an attempt earlier this could be NULL right?
        // I've had free impls crash when given NULL, so I check.
        if (it != _MyMap.end() &&
            NULL != it->second)
            free(it->second);

        // second query
        _MyMap.erase(i);
    }

    printf("_MyMap free'd and erased.  size now [%u]\n", _MyMap.size());

    return 0;
}

Вопросы в комментариях встроены

1 Ответ

3 голосов
/ 17 апреля 2019

Вы, вероятно, хотите это:

auto it = _Map.find(idUser);    
if (it != _Map.end())
{
    free(it->second);
    _Map.erase (it);
}

Но на самом деле не очень хорошая идея хранить таким образом необработанный указатель в коллекции. В идеале вы должны просто хранить данные непосредственно на карте, а не хранить на них указатель. В противном случае используйте std::unique_ptr, чтобы уничтожение указателя автоматически освободило данные.

...