Re: C++ std::string tries to free() a not allocated pointer ?
Re: C++ std::string tries to free() a not allocated pointer ?
- Subject: Re: C++ std::string tries to free() a not allocated pointer ?
- From: Jean-Denis Muys <email@hidden>
- Date: Thu, 19 Nov 2009 14:44:06 +0100
I got four answers to my request for help. Here is some additional info:
Scott Ribe wrote:
> Seems likely the heap is corrupted before you get to this point.
The heap is not corrupted. At least according to malloc itself. Moreover, I can ignore malloc's complain and the whole enchilada can go on running without crashing, nor leaking memory (that last bit being according to leaks).
Dave Hayes wrote:
> When you say the string length is zero does that mean that you are creating a std::string but not initializing it to any value?
No. the call sequence is to initialize the std::string with the (char*, length) constructor, where char* points to a 23-byte heap buffer starting with a zero byte, and length==0. In details, what the library does is:
buffer = new char[23];
buffer[0] = 0;
length = 0;
return SQLString(buffer, length);
Then I have this local SQLString, and malloc complains when it leaves it lexical scope.
> I would be surprised if it is using the stack.
I'm not 100% sure. All I can say is that the internal pointer in the std::string has a very different value from what malloc or new() typically returns. It's from a very different address range. Additionally, malloc_history on that address returns nothing. And finally, when this address is passed to free() from the std::string destructor, malloc complains that the block was never allocated. Any idea on how to find out where that address belongs?
Robert Schwalbe wrote:
> Try providing a copy constructor for your SQLString class.
> I believe without the presence of a copy constructor a blockmove/memcopy is performed and that will not copy the realStr member as it should.
The class does have a copy constructor. It actually has several. I omitted them because I didn't think they were relevant. I still don't think they are. Here they are:
const SQLString & operator=(const char * s)
{
realStr = s;
return *this;
}
const SQLString & operator=(const std::string & rhs)
{
realStr = rhs;
return *this;
}
const SQLString & operator=(const SQLString & rhs)
{
realStr = rhs.realStr;
return *this;
}
I can post the whole class if useful.(actually, it's open source code from mySQL, so widely available).
More over, the backtrace seems to indicate the correct constructor calling sequence:
#0 0x99056cb4 in std::string::_S_construct<char const*> ()
#1 0x99056d85 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string ()
#2 0x041fc8c7 in sql::SQLString::SQLString (this=0xb02e6a4c, s=0x4beccb0 "", n=0) at sqlstring.h:43
Clark S. Cox III wrote:
> That can't be it; there is absolutely nothing wrong with calling free() or delete on a NULL pointer.
And free() is not called on a NULL pointer. ~string calls delete on its internal pointer, which is not null. This internal pointer correctly points to a zero byte. Beyond that, I'm not sure how to determine where this pointer points to. It doesn't seem to be in the heap because malloc_history doesn't return anything about it.
Bottom line: I have made no progress, and can't see any other way to progress than learning assembly and the ABI and stepping through the standard C++ library. I have the feeling this is not right.
Jean-Denis
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden