I find myself in need of help. Now, I'm not all that unfamiliar with C++, but combining it with ATL provides a whole new level of confusion. Anyways, my problem: I (finally) managed to return an array of objects in my COM method to C# caller. But upon 'testing' (running said function a number of times repeatedly) I recognized a small memory leak.
IDL excerpt:
...
interface IDISControl : IDispatch{
...
[id(12)] HRESULT GetNets([out,retval] VARIANT* nets);
};
Header excerpt:
...
STDMETHOD(GetNets)(VARIANT* nets);
...
Code:
STDMETHODIMP CDISControl::GetNets(VARIANT* nets)
{
SNet *netz;
int32_t num;
int result, i;
result = DIS_GetNetNum(securityHandle, &num);
netz = new SNet[num];
result = DIS_GetNet(securityHandle, netz, num); //getting some data
CComSafeArray<IDispatch*> netArray;
CComObject<CDISNet> *net;
CComVariant *var;
netArray.Create(num, 0);
for (i = 0;i<num;i++){
CComObject<CDISNet>::CreateInstance(&net);
if (net == NULL)
return S_FALSE;
net->AddRef();
net->Convert(netz[i]);
netArray[i] = net;
net->Release();
net = NULL;
}
CComVariant val(netArray.Detach());
val.Detach(nets);
delete [] netz;
netArray.Destroy();
return S_OK;
}
I instantiate CDISNet objects and put some data in them (Convert()). I put them in my safearray and release. As I understand it, the responsibility for destroying them is transferred to safearray. Afterwards, I box the array in a VARIANT so I can fill my [out, retval] parameter. Since it's an out parameter, the responsibility for destruction should be transferred to caller (in my case C#, i.e. its GarbageCollector). I dispose of my dynamic array 'netz' and I destroy safearray wrapper.
So what am I missing? What is left allocated? (This project is really making me appreciate all the comforts of .net).
Help. Please.
EDIT: Further debugging revealed to me that the problem is certainely in my CComObject objects. They aren't being deallocated. If I delete net;
in each iteration the array also looses data. I'm unsure as how to rectify that...
EDIT2: Ok, I poked around this code for a bit, and the leak seems to go away when I comment out variant boxing. The problem is that I borrowed this piece of code from Visual Studio sample on safearrays. So, does anyone have any idea what's up with:
CComVariant val(netArray.Detach());
val.Detach(nets);
...and what to do about it?