EDIT: Thanks to everyone who pointed out the problem, and that it was discussed on Stack Overflow. I cast the last close vote myself.
A related question: neither CPP Reference on ostringstream
or ostringstream::str
state its a temporary. How did so many people know? Or is there different documentation I should have consulted?
I'm having a lot of trouble with memory errors under Debian 7.3 (x64) with GCC 4.7.2, -std=c++11
and std::ostringstream
. Its leading to bizaare results like https://stackoverflow.com/questions/21260815/which-r-in-this-create-table-error-message.
The full blown program uses Sqlite. Running a reduced case from the command line vs. Valgrind prints 2 different errors. The entire reduced case program is available at Code Viewer (I thought it was kind of long to post the entire sample here). All it does is initializes Sqlite, opens a database, creates a table, closes the database, and unitializes the database. And it reports errors if they occur. There's nothing else occurring.
Here's part of the reduced case program that simply tries to create a table. If the table exists, it should produce an error (which it does):
ostringstream qs;
qs.str().reserve(96);
qs << "CREATE TABLE test";
qs << "(";
qs << " userid INTEGER PRIMARY KEY AUTOINCREMENT,";
qs << " username TEXT,";
qs << " salt BLOB,";
qs << " hmac BLOB";
qs << ");";
const char* stmt = qs.str().c_str();
AC_ASSERT(NULL != stmt);
rc = sqlite3_exec(db, stmt, NULL, NULL, &err);
AC_ASSERT(rc == SQLITE_OK);
if(rc != SQLITE_OK)
{
ostringstream oss;
oss.str().reserve(96);
oss << "sqlite3_exec failed, error " << rc;
LogError(oss.str().c_str());
oss.clear(), oss.str("");
oss << "Sqlite error: " << err;
LogError(oss.str().c_str());
// Break, handle error
}
However, under command line, the message is:
sqlite3_exec failed, error 1
Sqlite error: table
Under Valgrind, the message is:
sqlite3_exec failed, error 1
Sqlite error: table test already exists
The program makes heavy use of ostringstream
, and Valgrind produces nearly 13 issues centered around them, 9 of which include operator delete(void*)
on the underlying basic_string
. For example, one is shown below (and line 76 from t.cpp
is const char* stmt = qs.str().c_str();
):
==14318== Invalid read of size 1
==14318== at 0x45ACC8: sqlite3_exec (sqlite3.c:94542)
==14318== by 0x405D07: main (t.cpp:79)
==14318== Address 0x5d89728 is 24 bytes inside a block of size 127 free'd
==14318== at 0x4C27870: operator delete(void*) (vg_replace_malloc.c:502)
==14318== by 0x530EB1F: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==14318== by 0x405CF1: main (t.cpp:76)
Does anyone have any ideas of what's going on here? Is it ostringstream
? Or perhaps GCC 4.7.2? Or maybe Debian's port?
(And sorry for the open ended question. I've run out of things to do).