1

I have a for loop that iterates through an XML document and finds a specified attribute, the pointer that points to the current node sits inside a boost::interprocess::unique_ptr and has a custom deletor to call the object's release() function. It seems that on every loop iteration the pointer gets deleted, but the release() function throws when that happens.

Could anyone suggest a solution? I thought about implementing a mechanism to check if it should be deleted, but I'm not sure how I'd do that...

Code:

typedef bi::unique_ptr<DOMNodeIterator, release_deleter> iterator_ptr; typedef bi::unique_ptr<DOMNode, release_deleter> node_ptr; iterator_ptr itera(document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true)); for(node_ptr current(itera->nextNode()); current != 0; current.reset(itera->nextNode())) // throws after one iteration... { 

....

objects release()

void DOMElementNSImpl::release() { if (fNode.isOwned() && !fNode.isToBeReleased()) throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager); // throws here if released after each loop iteration DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument; if (doc) { fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0); fParent.release(); doc->release(this, DOMMemoryManager::ELEMENT_NS_OBJECT); } else { // shouldn't reach here throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager); } } 

deleter:

struct release_deleter { template <typename T> void operator()(T* pPtr) const { pPtr->release(); } }; 

EDIT:

virtual DOMNodeIterator *createNodeIterator(DOMNode* root, DOMNodeFilter::ShowType whatToShow, DOMNodeFilter* filter, bool entityReferenceExpansion) = 0; virtual DOMNode* nextNode() = 0; 

1 Answer 1

2

I don't have visual 2010 for compiling and debugging at work, on ly at home. so I cannot be sure.

But Frankly I really do not like the concept that your iterator owns your pointer.

Your collection owns the pointer, the iterator doesn't ! its not its role..

In C++0x there are an complement to shared_ptr that is std::weak_ptr that you can construct from shared_ptr , allowing to consult and change the data, but having nothing to do with ownership, except becoming more or less inaccessible when the pointer onwed by the shared_ptr is released.

I would use a sort of std::weak_ptr for your iterators. But for unique_ptr I would guess it is a simple pointer over your data that takes the role of weak reference.

EDIT:

DOMNodeIterator * pIter = document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true); if(pIter==NULL) { return; } while(true) // be careful to infinite loops { DOMNode * pNode = pIter->nextNode(); if (pNode==NULL) { break; } // ... your visiting the nodes here. } 
Sign up to request clarification or add additional context in comments.

15 Comments

so if I understand correctly, current should be a weak_ptr and the iterator can still be a unique_ptr?
compiled with VS2003, using boost, not C++0x
sorry weak_ptr are shared_ptr counterpart, not unique_ptr counter_part (I have edited my post). I would use a simple pointer.
could you give me the prototype and implementation of document->createNodeIterator and itera->nextNode. I need to know precisely.
@Stephane, I have put the signatures already... I will see if I can find implementation...
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.