4 votes

Quelles sont les causes les plus fréquentes des fuites de mémoire COM ?

Quelles sont les causes les plus fréquentes des fuites de mémoire COM ?

J'ai lu que passer l'adresse d'un CComBSTR initialisé à une fonction en tant que paramètre [out] provoque une fuite. Je cherche à énumérer d'autres erreurs de programmation courantes comme celle-ci.

7voto

JaredPar Points 333733

Ne pas utiliser les types de wrapper RAII pour les objets COM. En particulier, ne pas utiliser CComPtr<> , CComBSTR y CComVARIANT<> . Ces objets aide prévenir les fuites en retirant au développeur la responsabilité de libérer la ressource sous-jacente. L'objet enveloppant impose la libération des ressources dans son destructeur.

Une autre cause de fuites ou de libérations accidentelles que j'ai observée est le résultat de la conversion implicite de la fonction CComPtr<T> a T* . Ceci est utile pour passer des objets enveloppés comme arguments. Mais elle peut poser des problèmes car elle permet la conversion implicite entre un objet RAII et un pointeur brut. Par exemple

CComPtr<IFoo> GetAFoo();  // Imagine if this creates the object
...
IFoo* pFoo = GetAFoo();   
pFoo->SomeCall();  

L'appel à SomeCall échouera probablement dans ce scénario car l'objet pFoo est mort à ce stade. Pourquoi ? La valeur a été renvoyée avec un compte de référence de 1 par GetAFoo, affectée à pFoo, puis décrémentée à 0 et supprimée parce que la valeur temporaire est sortie de la portée.

4voto

jeffamaphone Points 31732

Oublier d'appeler Release() quand il le faut. Utilisez CComPtr<>, CComVARIANT<> et CComBSTR pour vous aider.

2voto

sharptooth Points 93379

Il y a deux raisons principales : ne pas utiliser le RAII (pointeurs intelligents) et mal utiliser le RAII.

Si vous utilisez des pointeurs bruts - IInterface* ou BSTR vous risquez d'oublier d'appeler IInterface::Release() ou SysFreeString() et cela provoquera une fuite. Si vous utilisez des pointeurs intelligents de manière incorrecte, vous risquez également des fuites de mémoire. Une façon de le faire est celle que vous mentionnez - passer un CComBSTR::operator &() initialisé comme paramètre [out]. Il existe d'autres moyens, comme le passage de CComPtr::operator&() ou CCOmQIPtr::operator&() d'un pointeur intelligent initialisé en tant que paramètre [out] avec les ATLASSERTs désactivés. Ou créer n'importe quelle structure de type graphique avec une boucle et la libérer entièrement de sorte que les objets de la boucle détiennent chacun des smart pointeurs les uns vers les autres et empêchent la libération.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X