0

私は最近、C++ を使い始めなければならず、多くの問題を抱えています。ここでの問題は、同じバージョンの c++ でサポートされていない機能が必要なことです。たとえば、次のコードは 2 列のファイルを読み取り、トークン化し、辞書に保存します。

map<int,int>  ReadTables::lookupTable(string fpath) {
    map<int,int> lookup;    
    ifstream in;
    in.open(fpath.c_str());
    if ( !in.good()) {
        cout << "ERROR: Opening file failed.\n";
        exit (EXIT_FAILURE);
    }
    string line;
    const char delimiter[] = " ";
    vector<string> tokens;
    while (!in.eof()){
        getline(in,line);
        tokens = tokenize( line, delimiter );
        lookup[ atoi(tokens[0].c_str())] = atoi(tokens[1].c_str()); 
        //lookup[ stoi(tokens[0])] = stoi(tokens[1]);   
    } 

-std=c++0xフラグを使用しない限り、これは正常に機能します 。このバージョンを使用すると、次のようになりました。

 *** Break *** segmentation violation


===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007fc4782270ee in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007fc4781b9e8e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007fc47cb0a98e in TUnixSystem::StackTrace() () from /usr/local/lib/root/libCore.so
#3  0x00007fc47cb0a223 in TUnixSystem::DispatchSignals(ESignals) () from /usr/local/lib/root/libCore.so
#4  <signal handler called>
#5  0x00007fc478c64050 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x000000000040a83c in ReadTables::lookupTable (this=0x616500, fpath=...) at ../src/ReadTables.cpp:59
#7  0x000000000040ffd8 in main () at ../src/read.cpp:37
===========================================================


The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00007fc478c64050 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x000000000040a83c in ReadTables::lookupTable (this=0x616500, fpath=...) at ../src/ReadTables.cpp:59
#7  0x000000000040ffd8 in main () at ../src/read.cpp:37
==========================================================

また、このエラーが発生c11する使用する必要があることにも気付きました。stoi

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f26561b50ee in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007f2656147e8e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007f265aa9898e in TUnixSystem::StackTrace() () from /usr/local/lib/root/libCore.so
#3  0x00007f265aa98223 in TUnixSystem::DispatchSignals(ESignals) () from /usr/local/lib/root/libCore.so
#4  <signal handler called>
#5  0x00007f2656bf2050 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x000000000040ac44 in std::stoi (__str=..., __idx=0x0, __base=10) at /usr/include/c++/4.4/bits/basic_string.h:2567
#7  0x000000000040a8e6 in ReadTables::lookupTable (this=0x616500, fpath=...) at ../src/ReadTables.cpp:62
#8  0x0000000000410178 in main () at ../src/read.cpp:37
===========================================================


The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00007f2656bf2050 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x000000000040ac44 in std::stoi (__str=..., __idx=0x0, __base=10) at /usr/include/c++/4.4/bits/basic_string.h:2567
#7  0x000000000040a8e6 in ReadTables::lookupTable (this=0x616500, fpath=...) at ../src/ReadTables.cpp:62
#8  0x0000000000410178 in main () at ../src/read.cpp:37
===========================================================

ここで何が欠けていますか?どのバージョンを使用するかについての提案はありますか?

4

2 に答える 2

3

少なくとも 2 つの要素を含むベクターを返さない場合tokenize、コードはベクターの末尾を越えてアクセスし、未定義の動作が発生します。そのような未定義の動作の 1 つは、プログラムが C++98 で動作しているように見え、C++11 コンパイルで劇的に失敗することです。

于 2013-08-22T13:39:14.817 に答える
1

コードを大幅に簡素化できます。

std::map<int,int>  ReadTables::lookupTable(const std::string& fpath) 
{
    map<int,int> lookup;    
    std::ifstream fin(fpath.c_str());
    if (!fin.good()) 
    {
        cout << "ERROR: Opening file failed.\n";
        exit(EXIT_FAILURE); // should probably throw an exception here instead of exiting the program
    }

    // load all the integers from the file
    std::vector<int> v;
    std::copy(std::istream_iterator<int>(fin), std::istream_iterator<int>(), std::back_inserter<vector<int>>(v));
    assert(v.size() % 2 == 0); // assert that the file loaded key/value pairs
    for (i = 0; i < v.size(); i += 2)
    {
        lookup[v[i]] = v[i + 1];
    }

    fin.close();
    return lookup;
}

std::copyもう少し掘り下げる必要がありますが、呼び出しを微調整して直接ロードすることで、さらに単純化できる可能性がありますstd::map

于 2013-08-22T13:52:49.193 に答える