0

関数がいくつかのクラス (Rock) をglibc エラーmainで複数回実行しようとすると、プログラムが終了します。double free or corruption

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: 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

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

Conditional jump or move depends on unitialized value(s)Valgrind の出力の最初の行に関して、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.";
    }
}

何が問題なのかわかりませんし、実行可能な小さなプログラムを提供することもできません。

4

1 に答える 1

1

出力には2つの別々の問題がありvalgrindます。

1つ目は、初期化されていないメモリの使用です。これは、スタックのrock.cpp行で作成されたことを示しています。1139

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

その行を見て、変数を初期化します。

2番目の問題は、明らかにPostgresAPIからのメモリリークです。それはほぼ間違いなくあなたのクラッシュの原因ではありません。

これらはどちらも、ダブルフリーエラーの原因のようには見えません。これは、クラスに正しいコピーコンストラクタまたはコピー代入演算子を実装していないことが原因である可能性があります。

于 2013-01-16T00:31:23.270 に答える