std::unordered_map mit string Key, speicher deallokiert nach clear

Barista

Top Contributor
Ich benutze die C++ HashMap (unordered_map) mit strings als Schlüssel,
weil ich davon ausgehe, dass der hashCode und equal korrekt implementiert sind.


Hier die Header-Datei (angepasst):

C++:
#include <unordered_map>

class MyMap
{
public:
    MyMap();

    ~MyMap();

    void clear();

    void insert(uint8SizedBytes _keyBytes, uint16_t _value);

    uint16Option_t get(uint8SizedBytes _keyBytes);

private:
    // we use string as key because is ready for using
    std::unordered_map<std::string, uint16_t> map;
};

Hier die Cpp-Datei (angepasst):

C++:
#include "MyMap.h"

MyMap::MyMap()
{
}

MyMap::~MyMap()
{
    this->clear();
}

void Mymap::clear()
{
    this->map.clear();
}

void MyMap::insert(
        uint8SizedBytes _keyBytes,
        uint16_t _value)
{
    std::string key_asString{reinterpret_cast<char*>(_keyBytes.dataPtr), _keyBytes.dataLength};

    // TODO check for using copy constructor on using subscription operator
    this->map[key_asString] = _value;
}

uint16Option_t MyMap::get(uint8SizedBytes _keyBytes)
{
    std::string key_asString{reinterpret_cast<char*>(_keyBytes.dataPtr), _keyBytes.dataLength};

    auto it = this->map.find(key_asString);

    uint16Option_t valueOption = uint16OptionEmpty;

    if (it != this->map.end())
    {
        valueOption.value = it->second;
        valueOption.isPresent = true;
    }

    return valueOption;
}

uint8SizedBytes ist ein struct

C++:
typedef struct uint8SizedBytes
{
    uint8_t dataLength;
    uint8_t* dataPtr;
}uint8SizedBytes;

um byte (char) array und Länge zusammenzuhalten.

uint16Option_t ist ein struct um optional einen uint16_t-Wert zurückgeben zu können:

C++:
typedef struct{
    bool isPresent = false;
    uint16_t value;
}uint16Option_t;

const uint16Option_t uint16OptionEmpty = {false, 0};

Irgendwie sieht man sicher, dass ich vorher Java gemacht habe.

Meine Frage ist nun, ob nach dem Aufruf der Methode clear() aller allokierter Speicher freigegeben wurde.

key_asString liegt auf dem Stack (hat zwar Heap-Speicher), aber sollte am Ende der insert und get-Methode freigegeben sein.

Danke.
 

httpdigest

Top Contributor
http://www.cplusplus.com/reference/unordered_map/unordered_map/clear/
All the elements in the unordered_map container are dropped: their destructors are called, and they are removed from the container, leaving it with a size of 0.
Also: Ja, alle Strings werden deallokiert.

Da du die Map aber per Stack allokierst, brauchst du überhaupt gar nichts selbst clearen. Der Destruktor der map (und damit der Destruktor der Elemente in der Map) werden automatisch aufgerufen, wenn deine Instanz deallokiert wird:
http://www.cplusplus.com/reference/unordered_map/unordered_map/~unordered_map/
Destructs the container object. This calls each of the contained element's destructors, and dealocates all the storage capacity allocated by the unordered_map container.
 

Barista

Top Contributor
Ergänzend dazu habe ich gleich noch eine Frage.

Die move-Semantik verwirrt mich ziemlich, vor allem, weil es der gleiche Zuweisungsoperator = ist.

Mal angenommen, ich speichere in einer Map als value ein struct oder Objekt (ist ja eigentlich das Gleiche).

Das Objekt soll in der Map seine Heimat haben, also bei clear aus dem Speicher geräumt werden.

Solange es in der Map residiert will ich ab und zu mal gucken, eventuell auch ein paar Bytes mit memcpy rausklauben.

Wenn ich gucke, soll es nicht aus der Map entfernt werden, also kein move.

Ich möchte aber auch nicht, dass ich beim Gucken neuen Speicher un-freed allokiere, also copy ok, aber nur auf den Stack.

Wie kann ich das anstellen?

Wir haben hier C++ 14.

Einige Konstruktoren/Methoden erzeugt C++ automatisch, kann ich aber mit delete unterdrücken.

Eventuell muss ich einige Konstruktoren/Methoden selbst schreiben.
 

Ähnliche Java Themen

Neue Themen


Oben