He leído que el siguiente código provoca pérdida de memoria. Pero no entendí por qué.Fuga de memoria para CComBSTR
CComBSTR str;
pFoo->get_Bar(&str);
pFoo->get_Baf(&str);
¿Cómo se produce una fuga cuando no estamos asignando nada?
He leído que el siguiente código provoca pérdida de memoria. Pero no entendí por qué.Fuga de memoria para CComBSTR
CComBSTR str;
pFoo->get_Bar(&str);
pFoo->get_Baf(&str);
¿Cómo se produce una fuga cuando no estamos asignando nada?
Se pierde porque get_Bar()
y get_Baf()
no saben que está utilizando un CComBSTR.
Cuando toma la dirección de un CComBSTR lo que realmente está pasando al objeto subyacente es un puntero al miembro BSTR del CComBSTR.
El desglose de la secuencia:
CComBSTR str;
Esto inicializa el BSTR interna a NULL.
pFoo->get_Bar(&str);
get_Bar()
ve un BSTR * y lo llena con los datos reales. De esta manera:
HRESULT get_Bar(BSTR* arg) { *arg = SysAllocString(L"My String"); }
Ahora el BSTR interna de str
es un verdadero BSTR. Cuando CComBSTR se sale del alcance, eliminará el miembro str
.
Ahora, si llama al get_Baf()
en & str, el problema es que CComBSTR no sabe que está cambiando la cadena. Así que llama get_Baf()
así:
HRESULT get_Baf(BSTR* arg) { *arg = SysAllocString(L"My String"); }
Ahora get_Baf()
ha sobrescrito el valor original de BSTR interna str
's sin que nadie la liberación de los datos que se asigna por get_Bar()
.
Ta da - Memory leak.
Esta página Microsoft es probablemente el lugar donde se lee al respecto:
http://msdn.microsoft.com/en-us/library/bdyd6xz6.aspx
ProblemasPérdida de memoria
pasar la dirección de una CComBSTR inicializado a una función como un parámetro [out] causa una pérdida de memoria
El objeto CComBSTR está asignando memoria internamente. Evidentemente, hay casos en que no lo libera.
Si solo tenemos las dos primeras líneas CComBSTR str; pFoo-> get_Bar (&str); entonces no lo puedo causar una fuga y no hay necesidad de vaciar bien. – Julian
Eso es correcto. – Aaron
una vez que propone una advertencia fuga en CComBSTR, pero no estoy seguro de si todavía está allí (no tiene Visual Studio en esta máquina). Debería haber una afirmación que se dispara si intenta usar el operador & en un CComBSTR inicializado. Puede ser que necesite definir algún símbolo para habilitarlo - consulte la fuente de CComBSTR. –