2009-11-16 7 views
7

Ich habe gelesen, dass der folgende Code Speicherverlust verursacht. Aber ich habe nicht verstanden warum.Speicherleck für CComBSTR

CComBSTR str; 
pFoo->get_Bar(&str); 
pFoo->get_Baf(&str); 

Wie verursacht es ein Leck, wenn wir nichts zuweisen?

Antwort

11

Es leckt, weil get_Bar() und get_Baf() nicht wissen, dass Sie eine CComBSTR verwenden.

Wenn Sie die Adresse eines CComBSTR nehmen, was Sie tatsächlich an das zugrundeliegende Objekt übergeben, ist ein Zeiger auf das CCMBSTR BSTR-Mitglied.

Aufbrechen der Sequenz:

CComBSTR str; 

Dies initialisiert den internen BSTR auf NULL.

pFoo->get_Bar(&str); 

get_Bar() sieht ein BSTR * und füllt es mit aktuellen Daten. Wie folgt aus:

HRESULT get_Bar(BSTR* arg) { *arg = SysAllocString(L"My String"); } 

Nun ist die interne BSTR von str ist ein echter BSTR. Wenn CComBSTR den Gültigkeitsbereich verlässt, wird das Element str gelöscht.

Jetzt, wenn Sie get_Baf() auf & str aufrufen, ist das Problem, dass der CComBSTR nicht weiß, dass Sie die Zeichenfolge ändern. So rufen Sie get_Baf() wie folgt aus:

HRESULT get_Baf(BSTR* arg) { *arg = SysAllocString(L"My String"); } 

Jetzt hat get_Baf() den ursprünglichen Wert von str den internen BSTR, ohne dass jemand überschrieben, die Daten zu befreien, die von get_Bar() zugeordnet wurde.

Ta da - Speicherleck.

+0

Also, wenn wir nur die ersten beiden Zeilen haben CComBSTR str; pFoo-> get_Bar (&str); dann wird es kein Leck und es gibt keine Notwendigkeit, es richtig zu leeren. – Julian

+0

Das ist richtig. – Aaron

+0

Ich schlug einmal eine Leckwarnung in CComBSTR, aber ich bin mir nicht sicher, ob es noch da ist (Visual Studio auf diesem Computer nicht installiert. Es sollte eine Assertion vorhanden sein, die ausgelöst wird, wenn Sie versuchen, den Operator & auf einem initialisierten CComBSTR zu verwenden. Möglicherweise müssen Sie ein Symbol definieren, um es zu aktivieren - siehe Quelle von CComBSTR. –

4

Diese Microsoft-Seite ist wahrscheinlich die, wo man darüber lesen:

http://msdn.microsoft.com/en-us/library/bdyd6xz6.aspx

Speicherleck Probleme

Vorbei an der Adresse eines initialisierten CComBSTR auf eine Funktion als [out] Parameter verursacht ein Speicherleck.

Das CComBSTR-Objekt reserviert intern Speicher. Offensichtlich gibt es Fälle, in denen es es nicht freigibt.