My program exits when main function tries to run some class (Rock) more than once with a double free or corruption glibc error.
Valgrind returns:
==18672== Conditional jump or move depends on uninitialised value(s)
==18672== at 0x56F8554: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<unsigned long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, unsigned long) const (in /usr/lib64/libstdc++.so.6.0.17)
==18672== by 0x56F876C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, unsigned long) const (in /usr/lib64/libstdc++.so.6.0.17)
==18672== by 0x56FB945: std::ostream& std::ostream::_M_insert<unsigned long>(unsigned long) (in /usr/lib64/libstdc++.so.6.0.17)
==18672== by 0x431515: Rock::saveClustering(std::set<Attribution, std::less<Attribution>, std::allocator<Attribution> >) (rock.cpp:1406)
==18672== by 0x430C66: Rock::startRock() (rock.cpp:1321)
==18672== by 0x45DABC: main (main.cpp:207)
==18672== Uninitialised value was created by a stack allocation
==18672== at 0x42FF39: Rock::getFinalList(std::vector<Rock::BestLabel, std::allocator<Rock::BestLabel> >&) (rock.cpp:1139)
==18672==
==18672==
==18672== HEAP SUMMARY:
==18672== in use at exit: 292 bytes in 11 blocks
==18672== total heap usage: 86,558 allocs, 86,547 frees, 21,133,326 bytes allocated
==18672==
==18672== 292 (52 direct, 240 indirect) bytes in 1 blocks are definitely lost in loss record 11 of 11
==18672== at 0x4C2BCFB: malloc (vg_replace_malloc.c:270)
==18672== by 0x5F7FC94: nss_parse_service_list (in /lib64/libc-2.15.so)
==18672== by 0x5F80173: __nss_database_lookup (in /lib64/libc-2.15.so)
==18672== by 0xC1C15DB: ???
==18672== by 0x5F3592B: getpwuid_r@@GLIBC_2.2.5 (in /lib64/libc-2.15.so)
==18672== by 0x5050638: pqGetpwuid (in /opt/postgres_home/lib/libpq.so.5.3)
==18672== by 0x503C3BD: pqGetHomeDirectory (in /opt/postgres_home/lib/libpq.so.5.3)
==18672== by 0x503CCD4: getPgPassFilename (in /opt/postgres_home/lib/libpq.so.5.3)
==18672== by 0x503F78A: PasswordFromFile (in /opt/postgres_home/lib/libpq.so.5.3)
==18672== by 0x503FAAB: connectOptions2 (in /opt/postgres_home/lib/libpq.so.5.3)
==18672== by 0x503FD77: PQconnectStart (in /opt/postgres_home/lib/libpq.so.5.3)
==18672== by 0x503FDA5: PQconnectdb (in /opt/postgres_home/lib/libpq.so.5.3)
==18672==
==18672== LEAK SUMMARY:
==18672== definitely lost: 52 bytes in 1 blocks
==18672== indirectly lost: 240 bytes in 10 blocks
==18672== possibly lost: 0 bytes in 0 blocks
==18672== still reachable: 0 bytes in 0 blocks
==18672== suppressed: 0 bytes in 0 blocks
I’m not used to Valgring. Does it say that there was unitialized memory that was not free regarding postgres database access? The method I used to fetch the data was:
void Comum::fetchDB ( string sql_statement )
{
string conn_str ( "dbname=" + getDbName() + " user=" + getDbUser() );
pqxx::connection conn (conn_str);
pqxx::work txn (conn); // ex: domain = "voice"
pqxx::result r = txn.exec (sql_statement);
if ( r.size () == 0 ) {
std::cerr << "No records found for '" << domain << "'." << endl;
exit (12);
}
txn.commit ();
for (unsigned int u = 0; u != getNrFields (); ++u) {
vector <string> v;
v.reserve (r.size());
db_fetched.push_back (v);
}
for (unsigned int rownum = 0; rownum != r.size(); ++rownum) {
const pqxx::result::tuple row = r[rownum];
for (unsigned int colnum = 0; colnum != row.size(); ++colnum) {
const pqxx::result::field f = row[colnum];
db_fetched [colnum].push_back( f.c_str() );
}
}
conn.disconnect();
}
Regarding the first line of Valgrind’s output Conditional jump or move depends on unitialized value(s) the saveClusteringmethod is like follows:
void Rock::saveClustering (const set<Attribution> result)
{
string rock_dir = "rock";
string parent_dir = "output";
string dir = parent_dir + "/" + rock_dir;
// Create directory.
createDir (parent_dir);
createDir (dir);
// Build filename.
string filename;
map<unsigned int, AttType>::const_iterator citype = att_type.begin();
while (citype != att_type.end()) {
filename += citype->second.getName();
if (++citype != att_type.end()) {
filename += "-";
}
}
filename = parent_dir + "/" + rock_dir + "/" + filename + "-" + currentDateTime() + ".txt";
ofstream myfile(filename.c_str());
if (myfile.is_open()) {
for ( set<Attribution>::const_iterator ci = result.begin();ci != result.end(); ++ci ) {
myfile << ci->id << "\t";
for (vector<unsigned int>::const_iterator enci = ci->encodings.begin(); enci != ci->encodings.end(); ++enci) {
myfile << *enci << "\t";
}
myfile << ci->type << "\t" << ci->assignment << endl; // 1406 LINE
}
myfile << endl;
myfile.close();
} else {
cerr << "It was not possible to save decoder filename " << filename << endl;
cerr << "Press any key <ENTER> to continue.";
}
}
I just can’t see what’s wrong and can’t provide a small workable program.
There are two separate problems in the
valgrindoutput.The first is the use of uninitialized memory, which it tells you was created on the stack at
rock.cppline1139Look at that line and initialize the variable.
The second problem is a memory leak, apparently from the Postgres API. That’s almost certainly not the cause of your crash.
Neither of these looks like the cause of a double free error, that’s most likely caused by not implementing a correct copy constructor or copy assignment operator in your class.