You are right, it calls this to allocate the buffer:

static void* getExternalMemory(  MemoryManager* const allocator
                               , XMLSize_t const   sizeToAllocate)
{
   return allocator ? allocator->allocate(sizeToAllocate)
       : ::operator new(sizeToAllocate);
}

This function seems to be the reverse, but it is static:
static void returnExternalMemory(  MemoryManager* const allocator
                                 , void*                buffer)
{
    allocator ? allocator->deallocate(buffer)
        : ::operator delete(buffer);
}

So if you do not have an allocator, the ::operator delete(ptr) should be 
called, not simply delete ptr.  Does that work?  Either way, this seems 
incorrectly documented, and a poor interface.

john

-----Original Message-----
From: Vitaly Prapirny [mailto:[email protected]] 
Sent: Friday, December 25, 2009 10:43 AM
To: [email protected]
Subject: Re: Freeing memory allocated by Base64::encode

But there is no XMLString::release(XMLByte**) and that buffer
was allocated with new.

I think there is some inconsistency in the xerces library now.
Library should not allocate a buffer with plain new call
(maybe XMLPlatformUtils::fgMemoryManager->allocate instead) and library
should provide an API to release such a buffer without plain delete
call.

I suppose this trick should work right:

XMLPlatformUtils::Initialize();
XMLByte *b64 =
        Base64::encode(data, strlen(data), &n,
                XMLPlatformUtils::fgMemoryManager);
...
XMLPlatformUtils::fgMemoryManager->deallocate(b64);

Good luck!
        Vitaly

John Lilley wrote:
>> From the doc:
>
> NOTE: The returned buffer is dynamically allocated and is the responsibility 
> of the caller to delete it when not longer needed. You can call 
> XMLString::release to release this returned buffer.
> If a memory manager is provided, ask the memory manager to de-allocate the 
> returned
>
> I suggest calling XMLString::release()
>
> john
>
> -----Original Message-----
> From: k h [mailto:[email protected]]
> Sent: Thursday, December 24, 2009 6:31 PM
> To: [email protected]
> Subject: Freeing memory allocated by Base64::encode
>
> The code below triggers an assertion associated with memory corruption when
> compiled with MSVC 9.0 and run. I am using the current version of Xerces
> (3.0.1). The documentation at
> http://xerces.apache.org/xerces-c/apiDocs-3/classBase64.html#b0de37a376ae7355c973250a66b3a77asays
> that I should use XMLString::release to free the memory, however that
> is not possible without worrying casts, and in any case the documentation
> has been amended to say that delete should be used instead
> https://issues.apache.org/jira/browse/XERCESC-1847?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel.
> What am I doing wrong?
>
> BTW, anyone facing the same problem can just use a trivial custom memory
> manager as a workaround, assuming it is a xerces bug and there is no better
> solution.
>
> Many thanks for your help.
>
> #include<stdexcept>
> #include<cstring>
> #include<xercesc/util/Base64.hpp>
> #include<iostream>
>
> int main ()
> {
>                      const char * data = "hello";
>                      XMLSize_t n = 0;
>                      XMLByte * b64(
>                                    xercesc::Base64::encode(
> reinterpret_cast<const XMLByte*>(data),
>                                    (unsigned int)(std::strlen (data)),&n) );
>                      if (!b64)
>                      {
>                          throw(std::runtime_error("Unable to base64 encode
> data"));
>                      }
>
>                      std::cout<<  "encode(\""<<  data<<  "\") = "<<  b64<<
> std::endl;
>                      delete b64;  // memory corrupted here
>                      return 0;
> }
>

Reply via email to