You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xerces.apache.org by k h <xe...@googlemail.com> on 2009/12/25 02:31:17 UTC

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

RE: Freeing memory allocated by Base64::encode

Posted by John Lilley <jl...@datalever.com>.
Ah... pity I did not think to check "user error" :)
john

-----Original Message-----
From: k h [mailto:xerceslist.kh@googlemail.com] 
Sent: Friday, December 25, 2009 6:00 PM
To: c-users@xerces.apache.org
Subject: Re: Freeing memory allocated by Base64::encode

> 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.
>
>
I found the reason: it turns out that the ABIs used by MSVC in Debug and
Release modes are incompatible, and the compiler does not appear to warn in
any way when they are used together. Sorry I did not know that. It works
fine as posted earlier once correctly linked.

Re: Freeing memory allocated by Base64::encode

Posted by k h <xe...@googlemail.com>.
> 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.
>
>
I found the reason: it turns out that the ABIs used by MSVC in Debug and
Release modes are incompatible, and the compiler does not appear to warn in
any way when they are used together. Sorry I did not know that. It works
fine as posted earlier once correctly linked.

RE: Freeing memory allocated by Base64::encode

Posted by John Lilley <jl...@datalever.com>.
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:marl@mebius.net] 
Sent: Friday, December 25, 2009 10:43 AM
To: c-users@xerces.apache.org
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:xerceslist.kh@googlemail.com]
> Sent: Thursday, December 24, 2009 6:31 PM
> To: c-users@xerces.apache.org
> 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;
> }
>


Re: Freeing memory allocated by Base64::encode

Posted by Vitaly Prapirny <ma...@mebius.net>.
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:xerceslist.kh@googlemail.com]
> Sent: Thursday, December 24, 2009 6:31 PM
> To: c-users@xerces.apache.org
> 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;
> }
>


RE: Freeing memory allocated by Base64::encode

Posted by John Lilley <jl...@datalever.com>.
>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:xerceslist.kh@googlemail.com] 
Sent: Thursday, December 24, 2009 6:31 PM
To: c-users@xerces.apache.org
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;
}