Re: getline 'free' problem
Re: getline 'free' problem
- Subject: Re: getline 'free' problem
- From: Aron Nopanen <email@hidden>
- Date: Fri, 18 Sep 2009 00:26:57 +1200
On 17/09/2009, at 2:42 AM, Jason Foreman wrote:
On Sep 16, 2009, at 5:41 AM, Aron Nopanen wrote:
On Snow Leopard (using gcc 4.2), I'm getting a 'double free' error
in the guts of the C++ std::getline. The 'free' in question is
being performed by std::string::reserve. This happens any time I
run 'getline' (reading from cin) on a fresh, virgin string. (The
error is only seen in the Debug configuration.)
Try removing these definitions from the preprocessor flags of your
Debug configuration: "_GLIBCXX_DEBUG=1 _GLIBCXX_DEBUG_PEDANTIC=1" I
think there are some issues when those are defined that can cause
some unexpected behavior, such as what you're seeing.
Disabling _GLIBCXX_DEBUG does mask the problem. However, the issue is
still present (though it probably wouldn't cause any problem in
practice).
I spent some quality time with the std::string source code and figured
out what's going on. It comes down to some conditional compilation
driven by flag '_GLIBCXX_FULLY_DYNAMIC_STRING'. libstdc++.6.dylib was
apparently compiled with it set; my program was compiled without it set.
This flag is used in basic_string.h. If not defined, all newly-created
empty strings share a single, statically-defined internal
representation. In the functions that deal with reference-counting
shared internal string representations, there is conditionally-
compiled special-casing to check for this special empty-string
representation: reference counts aren't updated for it, and it's never
freed.
If _GLIBCXX_FULLY_DYNAMIC_STRING is defined, this special-casing goes
away. So, the empty string was created in my code (by these inlined
functions) using the special static empty string representation. The
call to std::getline in libstdc++.6.dylib then ended up dropping the
reference to this static representation. When doing so (because
_GLIBCXX_FULLY_DYNAMIC_STRING was defined), it decremented the
refcount and tried to free the non-malloced object. Hence: error.
Moral of the story: C++ programs on OS X should set this compiler
flag, to be consistent with the shared library settings. I'll file a
radar, as I think it should be set in the various versions of c+
+config.h, but it's commented out in all of them.
For anybody who's interested, here are the relevant bits from /usr/
include/c++/4.2.1/bits/basic_string.h:
void
_M_dispose(const _Alloc& __a)
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
-1) <= 0)
_M_destroy(__a);
} // XXX MT
void
_M_destroy(const _Alloc&) throw();
_CharT*
_M_refcopy() throw()
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
__gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
return _M_refdata();
} // XXX MT
Sorry for the digression; now back to your regular Cocoa programming.
Cheers,
Aron
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden