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;
> }
>