|
Boost : |
From: Chris Byrne (chris_at_[hidden])
Date: 2005-06-21 18:40:55
Hi,
I've been playing around with overloading global operator new and
delete and came across a problem concerning facets with VC7.1 in debug
mode. Internally facets are reference counted and destroyed in
[locale0.cpp - locale::_Locimp::~_Locimp()] via a macro _DELETE_CRT
[xdebug]. Now when _DEBUG is defined this macro will not call 'operator
delete' directly. So any facets added to a locale using 'operator new'
will not be freed with 'operator delete'.
In my case this leads to an assertion in dbgheap.c. This is because the
heap manager correctly recognizes that it was not responsible for the
allocation.
boost/archive/impl/basic_text_iprimitive.ipp:
add_facet(
std::locale::classic(),
new codecvt_null<BOOST_DEDUCED_TYPENAME IStream::char_type>
)
Minimal example is appended to the bottom of this post. As for a
possible work around (read hack) you can use _NEW_CRT instead of new
directly. A some what nicer hack^H^H^H^Hsolution may be to get add_facet
to perform the actual facet allocation itself using _NEW_CRT instead of
the caller.
Chris Byrne
////////////////////////////////////////////////////////////////////////////
#include <boost/archive/add_facet.hpp>
#include <boost/archive/codecvt_null.hpp>
#include <boost/shared_ptr.hpp>
#include <stdlib.h>
#include <malloc.h>
using namespace boost;
using namespace boost::archive;
using namespace std;
void* operator new(size_t size) {
char* block = reinterpret_cast<char*>(malloc(size + 1));
return block + 1;
}
void operator delete(void* address) {
if (!address) return;
char* block = reinterpret_cast<char*>(address);
free(block - 1);
}
int main() {
shared_ptr<locale> p;
p.reset(
add_facet(locale::classic(), new codecvt_null<char>)
// add_facet(locale::classic(), _NEW_CRT codecvt_null<char>)
);
p.reset();
return 0;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk