Delphi appears to be destroying objects before it should

delphi

Solution

You're calling `TXMLDocument.Create` with an `Owner` of `nil`. That means its lifetime is controlled via interface reference counting. In order for that to work, you need to actually use interfaces. Change `xmlDoc`'s type to `IXMLDocument` to maintain a reference, or else something internal to the VCL will free it when you're not expecting it.

Problem

I'm working on a Delphi wrapper for the Googledocs api using Delphi XE2. I generated all the classes using the XML Data Binding Wizard. This is a lot easier to explain using code, so here is the function my test calls. ``` function TGoogleDocsApi.GetEntries : IXMLEntryTypeList; var httpHelper : IHttpHelper; xml, url : string; xmlDoc : TXmlDocument; ss : TStringStream; feed : IXmlFeedType; begin ss := TStringStream.Create; httpHelper := THttpHelper.Create; if(fToken.IsExpired) then fToken.Refresh(fClientId,fClientSecret); url := BaseUrl + 'feeds/default/private/full?showfolders=true&access_token='+fToken.AccessToken+'&v=3'; xml := httpHelper.GetResponse(url); ss.WriteString(xml); ss.Position := 0; xmlDoc := TXmlDocument.Create(nil); xmlDoc.LoadFromStream(ss); feed := GoogleData2.Getfeed(xmlDoc); Result := feed.Entry; end; ``` Now, at the point that 'end' is hit, Result.ChildNodes has an address in memory and it's count is 20. IXMLEntryTypeList is a child interface of IXMLNodeCollection. Now here is my test: ``` procedure TestIGoogleDocsApi.TestGetEntries; var ReturnValue: IXMLEntryTypeList; begin ReturnValue := FIGoogleDocsApi.GetEntries; if(ReturnValue = nil) then fail('Return value cannot be nil'); if(ReturnValue.ChildNodes.Count = 0) then fail('ChildNodes count cannot be 0'); end; ``` On the second if statement, I get an access violation saying "Access violation at address 0061A55C in module 'GoogleDocsApiTests.exe'. Read of address 00000049" and when I look at my watches for ReturnValue and ReturnValue.ChildNodes, I see that ReturnValue has the same address as Result did in the TGoogleDocsApi.GetEntries method, but it gives me the access violation on the watch for ReturnValue.ChildNodes and in the TGoogleDocsApi.GetEntires method, Result.ChildNodes has a valid address and its properties are filled out. To me it looks like Delphi is releasing the ChildNodes property somewhere along the line, but that doesn't make sense to me since ReturnValue should still be referencing it which (I think) should keep it around. Any ideas what might be going on?

Original source