2016-10-08 3 views
1

ich eine solche Klasse:Wie Speicher nach dem Stradd freigeben?

class Kot{ 
public: 
    string name; 
}; 

ich eine Instanz davon:

Kot* kot = new Kot; 
kot->name = "John"; 

Dann möchte ich ein Duplikat Zeichenfolge erstellen:

string name; 
name = strdup(kot->name.c_str()); 

I strdup weil ich möchte delete kot und nur name variable . But I have a 5 bytes memory leak due to name memory allocation. How can I free it safely? I tried to do löschen & name`, aber ich habe:

Process finished with exit code 134 (interrupted by signal 6: SIGABRT) 
+1

Verwenden Sie nicht strdup, wenn Sie C++ - Code schreiben, sondern einfach einem neuen String zuweisen, dh 'name = kot-> name;' dann erhalten Sie eine Kopie –

Antwort

2

Sie haben wahrscheinlich ein 5-Byte-Speicherleck festgestellt, aber es ist nicht wegen der string.

Jeder Anruf an strdup erstellt eine neue char[] der Größe, die der Länge der Zeichenfolge entspricht. Sie sollten es an einen rohen Zeiger char* binden und es irgendwann entfernen.

Was Sie stattdessen getan haben, ist, dass Sie einen temporärenchar* Zeiger erstellen. Nennen wir es temp für unsere Zwecke. Der temp String wird dann an den Konstruktor std::string übergeben. Die std::string macht eine weitere Kopie davon, die ursprüngliche temp bleibt intakt.

Dann verschwindet der Zeiger temp einfach, ohne den Speicher ordnungsgemäß zu löschen.

Am Ende, wenn das std::string Objekt zerstört wird, löscht es ordnungsgemäß seine eigene, private Kopie der Zeichenfolge. Aber die Erinnerung, auf die zuvor von temp hingewiesen wurde, wird niemals freigegeben.

Eine schnelle Lösung wäre:

char* temp = strdup(kot->name.c_str()); 
name = temp; 
free(temp); 

aber Sie haben nicht einmal das zu tun haben! Wenn Sie ein Objekt std::string einem anderen zuweisen, erstellen Sie bereits eine ordnungsgemäße Kopie seines Inhalts. Also:

name = kot->name; 

wird höchstwahrscheinlich genau das tun, was Sie versuchen, bereits zu erreichen - das Erstellen einer Kopie von kot->name in Ihrem name. In einem solchen Szenario werden name und kot->name zwei völlig separate Strings mit demselben (kopierten) Inhalt. Von diesem Zeitpunkt an hat das Ändern/Löschen keinen Einfluss mehr auf den anderen.

+0

'name = kot-> name;' es ist schlecht raten, weil ich 'kot' löschen und nur name-variable verwenden möchte. Muss ich in diesem Fall also strdup verwenden? –

+0

@RomaKarageorgievich: Sie können Kot löschen, ohne den zugewiesenen Namen zu beeinflussen. C++ - Zeichenfolgen sind richtige Klassen, die ihren eigenen Speicher verwalten. Insbesondere wird die Zuweisung 'name = kot-> name 'eine * neue * Kopie des Textes machen, völlig unabhängig von der in' kot-> name' gespeicherten. – celtschk

1

Sie haben ein Speicherleck hier:

name = strdup(kot->name.c_str()); 

, weil man nie Speicher von strdup zugewiesen freigeben.

dieses Problem vermeiden Sie einfach name vom kot->name konstruieren kann:

name = kot->name; 
+0

Nein, ich möchte genau ein Duplikat von 'kot- haben. > Name' Zeichenfolge. –

+0

@RomaKarageorgievich Was ist ein genaues Duplikat in Ihrem Verständnis? –

+0

@Roma Karageorgievich: Aber "exakt duplizieren" ist genau das, was 'name = kot-> name' erzeugt. Ihr 'strdup' ändert nichts in dieser Hinsicht, abgesehen davon, dass ein Speicherleck erzeugt wird. – AnT

2

Sie free() verwenden, nicht delete.

Per the standard documentation:

Die strdup() Funktion wird ein Zeiger auf eine neue Zeichenfolge zurück, die ein Duplikat der Zeichenfolge auf den s. Der zurückgegebene Zeiger kann an free() übergeben werden. Ein Nullzeiger wird zurückgegeben, wenn die neue Zeichenfolge nicht erstellt werden kann.

+0

free (& name) gibt mir auch einen Fehler. –

+0

@RomaKarageorgievich * free (& name) gibt mir auch einen Fehler. * Und was ist '& name'? '& name' ist nicht der Wert, der von' strdup() 'zurückgegeben wird. –

Verwandte Themen