1

This is on Visual Studio 2008 on a dual-core, 32 bit Vista machine. In the debug code this runs fine, but in Release mode this bombs:

void getFromDB(vector<string>& dates) {
    ...
    sql::Resultset res = stmt->executeQuery("SELECT FROM ...");
    while (res->next()) {
       string date = res->getString("date");
       dates.push_back(date);
    }   // <<< crashing here (line 56)
    delete res;
}

The MySQL C++ connector has this method in it's ResultSet:

virtual std::string getString(const std::string& columnLabel) const = 0;

For some reason in the release compiled (against a MySQL C++ connector DLL) this crashes at the end of the loop with a heap corruption:

HEAP[sa-ms-release.exe]: Invalid address specified to RtlFreeHeap( 024E0000, 001C4280 ) Windows has triggered a breakpoint in sa-ms-release.exe.

    ntdll.dll!_RtlpBreakPointHeap@4()  + 0x28 bytes 
    ntdll.dll!_RtlpValidateHeapEntry@12()  + 0x713e8 bytes  
    ntdll.dll!_RtlDebugFreeHeap@12()  + 0x9a bytes  
    ntdll.dll!@RtlpFreeHeap@16()  + 0x145cf bytes   
    ntdll.dll!_RtlFreeHeap@12()  + 0xed5 bytes  
    kernel32.dll!_HeapFree@12()  + 0x14 bytes   
>   sa-ms-release.exe!free(void * pBlock=0x001c4280)  Line 110  C
    sa-ms-release.exe!std::allocator<char>::deallocate(char * _Ptr=0x001c4280, unsigned int __formal=32)  Line 140 + 0x9 bytes  C++
    sa-ms-release.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Tidy(bool _Built=true, unsigned int _Newsize=0)  Line 2158 C++
    sa-ms-release.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >()  Line 907    C++
    sa-ms-release.exe!StyleData:: getFromDB( std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & dates)  Line 56 + 0x69 bytes    C++

I think I may be violating some basic C++ rule that causes the destructor to be called on a string I want to preserve inside the vector.

If I replace

string date = res->getString("date")

with

string date = string ("2008-11-23");

everything works fine. It seems to have to do with the string returned from the MySQL C++ Connector getString() method. The returned string is destroyed and that causes the problem, I guess. But more likely something else is wrong. I am using the release (opt) MySQL connector.

Martin Stein
  • 306
  • 3
  • 11
  • 1
    Which STL version, SDK or VS you are compiling against?? – vpram86 Sep 29 '09 at 18:39
  • Poviding line numbers in your code might help (the last line in message above specifies line 56 in StyleData::getFromDB). Disassebly might help even more... – Tomek Sep 29 '09 at 18:44
  • what is the signature of sql::Resultset::getString(...);? – Frank Bollack Sep 29 '09 at 18:51
  • 1
    remember, just because it happens to crash somewhere doesn't mean that's where the error is - the damage might be done in an entierly different part – nos Sep 29 '09 at 19:09
  • It returns `std::string` (i.e. not a reference). His code is fine. – Pavel Minaev Sep 29 '09 at 19:34
  • 1
    Are you sure you're linking against VS2008 version of the MySQL connector, and not against VS2005 version? (see http://dev.mysql.com/downloads/connector/cpp/1.0.html)? – Pavel Minaev Sep 29 '09 at 19:35

2 Answers2

6

imho, problem may arise from VS run time libraries.That means, DLL you use for sql connector methods are compiled not with "multi thread dll" code generation option.So different versions of strings are passed through parameters and they chrash.I think you should check this code generation flag.

Qubeuc
  • 982
  • 1
  • 11
  • 22
  • Yeah. I too guess that will be the reason. Perhaps /MD or /MDd ? If i remember correctly. If these are there in DEBUG mode options, then definitely that's the reason – vpram86 Sep 29 '09 at 19:33
  • The MySQl Connector is compiled with /MD and my code with /MT. Now both are /MD. Code now works!!! Thanks – Martin Stein Sep 29 '09 at 19:46
3

You can have a look at this thread

Even though the problem is reported on XP, the situation is same. The reason being "string getting destroyed on different heap rather than the one it was created on."

In your case, the string gets allocated at the Connector DLL heap which was getting freed in Application heap.

I guess you can find some good suggestions over that thread. (Compiling both DLL and APP using same runtime, or passing string by reference between application and dll calls)

vpram86
  • 5,860
  • 4
  • 28
  • 40
  • The reason was two conflicting runtime libraries specified. I think this is quite complex. Do the two DLLs have to have separate heaps? Is this the same under Unix/Linux? Java is so much easier. – Martin Stein Sep 29 '09 at 19:51
  • I dont think this is same under Linux...Yeah :).. I too feel java is easier in these cases, by abstracting all lower level details... But there might be specific reasons why they designed it that way! I can never understand that much complex reasoning logic behind these decisions!! :) – vpram86 Sep 29 '09 at 19:58