lizh06 / ticpp

Automatically exported from code.google.com/p/ticpp
0 stars 0 forks source link

Memory leak with ticpp::Element::GetDocument() #61

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Load an xml (will most likely work just creating a document)
2. Get an element from the XML
3. Call GetDocument() on the element

What is the expected output? What do you see instead?
Should get a pointer to the document which you then delete, which will 
decrement the ref count

What version of the product are you using? On what operating system?
svn trunk, windows 7

Please provide any additional information below.
When you call GetDocument on an Element, it eventually (Node::GetDocument()) 
calls this code:

Document* temp = new Document( doc );
doc->m_spawnedWrappers.push_back( temp );
return temp;

The pointer that gets returned from this function is impossible to destroy 
cleanly (as far as I'm aware).

Either, you delete the pointer returned from GetDocument(), in which case, you 
get a double-free error when TiCppRC::DeleteSpawnedWrappers() is called when 
the last reference to the document is destroyed. Or you do not delete it, which 
leaves the document with a reference count of 1 and lots of nice memory leaks 
due to the document not being destroyed.

Original issue reported on code.google.com by Pyr...@googlemail.com on 20 Nov 2010 at 4:53

GoogleCodeExporter commented 9 years ago
The only workaround I've found is to re-assign to the pointer received from 
GetDocument, i.e.

ticpp::Document* doc = node->GetDocument();

... subsequently ...

doc = ticpp::Document();

Original comment by rldu...@gmail.com on 2 Jun 2014 at 8:47

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Need to amend previous comment. Instead of:

   doc = ticpp::Document();

needs to be:

   *doc = ticpp::Document();

Sorry for the typo...

Original comment by rldu...@gmail.com on 3 Jun 2014 at 3:29

GoogleCodeExporter commented 9 years ago
OK, one more note and I'll leave it alone.  Here's what I'm using as a work 
around:

class DocumentPtr
{
public:
  DocumentPtr(ticpp::Node const * node) : document(node->GetDocument()) {}
  ~DocumentPtr() { *document = ticpp::Document(); }
  ticpp::Document* operator->() { return document; }
  ticpp::Document& operator*() { return *document; }
  operator ticpp::Document&() { return *document; }
  operator ticpp::Document*() { return document; }

private:
  DocumentPtr(DocumentPtr const&);              // No copy construct
  DocumentPtr& operator=(DocumentPtr const &);  // No copy assignment
  ticpp::Document* document;
};

I haven't beat on it a bunch but it works OK in this context:
   ticpp::Element const * e = findElement(DocumentPtr(refElem), path);
where
   ticpp::Element const * e = findElement(refElem->GetDocument(), path);
didn't. 

FWIW the signature for findElement is:
   ticpp::Element* findElement(ticpp::Node const *, std::string const&)

Original comment by rldu...@gmail.com on 3 Jun 2014 at 4:46