Ho letto che il seguente codice causa perdite di memoria. Ma non ho capito perché.Perdita di memoria per CComBSTR
CComBSTR str;
pFoo->get_Bar(&str);
pFoo->get_Baf(&str);
Come provoca una perdita quando non stiamo allocando nulla?
Ho letto che il seguente codice causa perdite di memoria. Ma non ho capito perché.Perdita di memoria per CComBSTR
CComBSTR str;
pFoo->get_Bar(&str);
pFoo->get_Baf(&str);
Come provoca una perdita quando non stiamo allocando nulla?
Si perde perché get_Bar()
e get_Baf()
non si sa che si sta utilizzando un CComBSTR.
Quando si prende l'indirizzo di un CComBSTR, ciò che si sta passando all'oggetto sottostante è un puntatore al membro BSTR di CComBSTR.
Suddividendo la sequenza:
CComBSTR str;
Questo inizializza BSTR interna NULL.
pFoo->get_Bar(&str);
get_Bar()
vede un BSTR * e la riempie con i dati reali. Come questo:
HRESULT get_Bar(BSTR* arg) { *arg = SysAllocString(L"My String"); }
Ora il BSTR interna di str
è un vero e proprio BSTR. Quando CComBSTR esce dall'ambito, verrà eliminato il membro str
.
Ora se si chiama get_Baf()
su & str il problema è che CComBSTR non sa che si sta modificando la stringa. Così si chiama get_Baf()
in questo modo:
HRESULT get_Baf(BSTR* arg) { *arg = SysAllocString(L"My String"); }
Ora get_Baf()
ha sovrascritto il valore originale di BSTR interno str
s' senza che nessuno liberando i dati che è stato assegnato dal get_Bar()
.
Ta da - Perdita di memoria.
Questa pagina Microsoft è probabilmente il quale si legge a questo proposito:
http://msdn.microsoft.com/en-us/library/bdyd6xz6.aspx
ProblemiPerdita di memoria
Passando l'indirizzo di un CComBSTR inizializzato a una funzione come parametro [out] causa una perdita di memoria.
L'oggetto CComBSTR sta allocando memoria internamente. Evidentemente ci sono casi in cui non lo rilascia.
Quindi se abbiamo solo le prime due righe CComBSTR str; pFoo-> get_Bar (&str); quindi non causerà una perdita e non è necessario svuotarlo correttamente – Julian
Questo è corretto – Aaron
Una volta ho proposto un avviso di perdita in CComBSTR, ma non sono sicuro che sia ancora lì (non avere Visual Studio su questa macchina). Dovrebbe esserci un'affermazione che si attiva se si tenta di utilizzare l'operatore e su un CComBSTR inizializzato. Potrebbe essere necessario definire un simbolo per abilitarlo: vedere l'origine di CComBSTR. –