2013-01-15 75 views
0

main函数尝试运行某个类(Rock)多于一次且出现glibc错误时,我的程序将退出。双重释放或损坏错误 - valgrind

Valgrind的回报:

==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: [email protected]@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 

我不习惯Valgring。是否说有关于postgres数据库访问的单元化内存不是免费的?该方法我用来获取数据是:

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(); 
} 

关于Valgrind的输出的第一行Conditional jump or move depends on unitialized value(s)saveClustering方法类似如下:

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."; 
    } 
} 

我看不出有什么错误,可以”提供一个小的可行的程序。

+1

它表示单位化值是在Rock :: getFinalList中创建的。也许这是一个开始的好地方? – JaredC

+0

请缩进您的代码。 – Csq

+0

为什么在查询中间有'txn.commit();'语句? – Csq

回答

1

valgrind输出有两个不同的问题。

首先是使用未初始化的内存中,它会告诉你在rock.cpp行栈上创建1139

==18672== at 0x42FF39: Rock::getFinalList(std::vector<Rock::BestLabel, std::allocator<Rock::BestLabel> >&) (rock.cpp:1139) 

看看该行并初始化变量。

第二个问题是内存泄漏,显然来自Postgres API。这几乎肯定不是你的崩溃的原因。

这些看起来都不是双免费错误的原因,这很可能是由于在类中没有实现正确的复制构造函数或复制赋值运算符所致。

相关问题