Warum ist der Speicher noch zugänglich, nachdem std :: map :: clear () aufgerufen wurde?
Beobachten ich seltsame Verhalten von std::map::clear(). Diese Methode nennen soll element der Destruktor aufgerufen, aber Speicher ist immer noch zugänglich, nach dem Aufruf von clear().
Beispiel:
struct A
{
~A() { x = 0; }
int x;
};
int main( void )
{
std::map< int, A * > my_map;
A *a = new A();
a->x = 5;
my_map.insert( std::make_pair< int, *A >( 0, a ) );
//addresses will be the same, will print 5
std::cout << a << " " << my_map[0] << " " << my_map[0]->x << std::endl;
my_map.clear();
//will be 0
std::cout << a->x << std::endl;
return 0;
}
Die Frage ist, warum ist variabel a
noch zugänglich, nachdem der Destruktor aufgerufen wurde, die von map::clear()? Brauche ich zu schreiben delete a;
nach dem Aufruf my_map.clear()
oder ist es sicher, überschreiben Sie den Inhalt a
?
Vielen Dank im Voraus für Eure Hilfe,
sneg
InformationsquelleAutor der Frage sneg | 2009-02-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
std::map nicht gelingt, die Erinnerung verweist der pointer-Werte - es ist bis zu Ihnen, es selbst zu tun. Wenn Sie nicht möchten, verwenden smart-Pointer, Sie können schreiben, ein Allzweck-freie & clear-Funktion wie folgt:
Und Verwendung:
;
InformationsquelleAutor der Antwort
Wenn Sie speichern Zeiger auf einer Karte (oder eine Liste oder etwas in der Art) SIE sind verantwortlich für das löschen den Zeiger, da die Karte nicht kennen, wenn Sie erstellt wurden, mit neuen, oder nicht. Die Funktion "löschen" nur ruft Destruktoren wenn Sie keine Zeiger verwenden.
Oh, und noch eins: der Aufruf eines destruktors (oder sogar der Aufruf von delete) bedeutet nicht, dass der Speicher kann nicht mehr zugegriffen werden. Es bedeutet nur, dass Sie werden Zugriff auf Müll, wenn Sie tun.
InformationsquelleAutor der Antwort Marc
Weil
map.clear()
Destruktor aufgerufen, der die Daten in die Karte, in deinem Fall, der Zeiger aufa
. Und diese tut nichts.Möchten Sie vielleicht einige Art smart pointer in der Karte, für die Speicher belegt durch
a
werden automatisch zurückgefordert.BTW, warum stellst du die Vorlage Argumente im Aufruf an
make_pair
? Das Vorlage-argument Abzug sollte ziemlich gut zu tun hier.InformationsquelleAutor der Antwort jpalecek
Wenn Sie frei ein Stück von heap-Speicher, dessen Inhalt nicht unwiderruflich gelöscht wird. Sie sind lediglich für die Zuweisung wieder. Natürlich sollten Sie den Speicher nicht zugänglich, da die Auswirkungen der Zugriff auf nicht zugewiesenen Speicher nicht definiert sind.
Tatsächlich verhindern, dass Zugriff auf eine Speicherseite geschieht auf einem niedrigeren Niveau, und std-Bibliotheken nicht.
Beim reservieren von Speicher mit new, müssen Sie es löschen sich selbst, es sei denn, Sie verwenden ein smart pointer.
InformationsquelleAutor der Antwort John Smith
Jeder container speichert Ihr Objekt Geben und Aufruf der entsprechenden Konstruktoren: interner code jeder Knoten könnte wie folgt Aussehen:
Wenn Sie reservieren, es passiert durch den Bau der val basiert auf geben und dann zu verlinken. Etwas ähnliches wie:
Wenn Sie es löschen, ruft die entsprechenden Destruktoren.
Beim speichern Referenzen (Pointer) es wird nicht jeder Konstruktor-Aufruf, noch es zu zerstören.
InformationsquelleAutor der Antwort FL4SOF
Nachdem er in den letzten 2 Monaten Essen, schlafen und atmen Karten, habe ich eine Empfehlung. Lassen Sie die Karte zuweisen, die eigenen Daten, Wann immer möglich. Es ist viel sauberer, für genau die Art von Gründen, Sie sind Hervorhebung hier.
Es gibt auch einige subtile Vorteile, wenn man z.B. kopieren von Daten aus einer Datei oder socket zu der Karte, die Daten, die Speicherung der Daten vorhanden ist, sobald der Knoten vorhanden ist, weil, wenn die Karte Aufrufe von malloc() reservieren, die Knoten, die er reserviert Speicher für beide der Schlüssel und die Daten. (AKA map[key].erste und map[key].Sekunde)
Dies ermöglicht die Verwendung der Zuweisungs-operator anstelle von memcpy () und benötigt 1 Anruf weniger malloc () -, die Sie stellen.
Ein paar Vorsichtsmaßnahmen zu beachten sind, hingewiesen hier.
geben Sie einige Gedanken, wie und wo zu "verankern" Ihre Karten. SPRICH: wo Sie deklariert sind. Wenn Sie nicht wollen, gehen aus dem Geltungsbereich versehen. die main{} ist immer sicher.
Ich hatte sehr viel Glück, und freue mich sehr kritisch Karte zuordnen einer Struktur, wie es der Knoten der Daten, und dass struct "Anker" eine Karte. Während anonyme Strukturen sind aufgegeben worden, die von C++ (eine schreckliche, schreckliche Entscheidung, die rückgängig gemacht werden MUSS), Karten der 1. struct-member funktionieren genauso wie die anonymen Strukturen. Sehr glatt und sauber mit Größe null-Effekte. Übergeben Sie einen Zeiger auf das Blatt im Besitz struct, oder eine Kopie der struct-by-value in eine Funktion aufrufen, funktionieren beide sehr gut. Sehr zu empfehlen.
sparen Sie sich eine RIESIGE Menge Verwirrung und eingeben, und verwenden Sie typedefs für Ihre Karten, wie so.
pass Verweise auf Karten mit dem typedef und & - operator, wie in
ULNG DestroyCustomer_callMap(CUST_SUM Summary, CDR_MAP& cdrMap, KCI_MAP& kciMap)
verwenden Sie die "auto" - Variablen Datentyp für Iteratoren. Der compiler herausfinden, von dem Typ angegeben, der rest der for () - Schleife, welche Art von Karte typedef zu verwenden. Es ist so sauber, es ist fast Magie!
for(auto itr = Summary.callMap.begin(); itr!= Summary.callMap.end(); ++itr) {
definieren, einige manifest-Konstanten, um die Rückkehr aus .löschen und .empty() mehr sinnvoll.
if(ERASE_SUCCESSFUL == cdrMap.erase (itr->second->iGUID)) {
gegeben, dass "intelligente Zeiger" sind wirklich einfach, um eine Referenz zu zählen, denken Sie daran, Sie können immer Ihre eigene Referenz-Zählung, die eine vermutlich ein sauberer und deutlicher. Kombinieren Sie dies mit #5 und #10 oben, können Sie schreiben einige nette clean code wie dieser.
verwenden einen Zeiger auf hängen auf einer Karte Knoten, ordnet alles für sich selbst, SPRICH: keine Benutzer-Zeiger zeigt auf Benutzer malloc()ed") Objekte, die gut funktioniert, ist möglicherweise effizienter, und, und verwendet werden, mutieren die Daten eines Knotens, ohne Nebenwirkungen, in meiner Erfahrung.
auf dem gleichen Thema, wie ein pointer verwendet werden, sehr wirksam zur Erhaltung der Zustand eines Knotens, wie in
pThisCDRLeafData
oben. Mit der Verabschiedung dieser auf eine Funktion, die mutiert/Veränderungen, die bestimmten Knoten Daten ist sauberer als bei der übergabe einer Referenz auf die Karte und den Schlüssel brauchte, um wieder zu den KnotenpThisCDRLeafData
verweist.Iteratoren sind keine Zauberei. Sie sind teuer und langsam, wie Sie die Navigation in der Karte, um Werte. Für eine map-holding eine million Werte, die Sie Lesen können, einen Knoten basierend auf einem Schlüssel-bei etwa 20 Millionen pro Sekunde. Mit Iteratoren ist es wohl ~ 1000 mal so langsam.
Ich denke, dass etwa deckt es für jetzt. Wird aktualisiert, wenn eine dieser änderungen oder zusätzliche Einblicke zu teilen. Ich bin besonders genießen mit dem STL durch C-code. SPRICH: nicht die Klasse im Blick und überall. Sie einfach keinen Sinn im Kontext arbeite ich in, und es ist nicht ein Problem. Viel Glück.
InformationsquelleAutor der Antwort user2548100