Martin Stein
Martin Stein

Reputation: 305

Memory corrupt in adding string to vector<string> loop

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.

Upvotes: 1

Views: 3615

Answers (2)

vpram86
vpram86

Reputation: 6000

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)

Upvotes: 3

Qubeuc
Qubeuc

Reputation: 982

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.

Upvotes: 6

Related Questions