0

読んで保存しようとしている単語がたくさん含まれているファイルがあります。ソートマップを作成しようとしています。

プログラムの最初に、各エントリの情報を格納するために使用される構造体を宣言しました。

typedef struct dictionary{ std::string word; unsigned char * hash; char *hex; } a_dictionary;
unordered_map<char * , a_dictionary * > Mymap;

これは単語を保存するために実行しているコードですが、何らかの理由でmyMapが正しく記述されていません

if (myfile.is_open())
        {
            LARGE_INTEGER freq, before, after;
            QueryPerformanceFrequency(&freq);
            QueryPerformanceCounter(&before);
            while ( myfile.good() )
            {
                getline (myfile,line);

                a_dictionary * dic = new dictionary(); // after each line create
                dic->word = line;


                const char * c= line.c_str();
                sha1::calc(c,line.length(), hash);//encrypts the word

                dic->hash = hash;

                sha1::toHexString(hash,hex_str);//encrypts the word
                dic->hex = hex_str;

                Mymap.insert(std::make_pair(hex_str, dic));
            }
            QueryPerformanceCounter(&after);
            float fElapsed = static_cast<float>(after.QuadPart - before.QuadPart) / freq.QuadPart;
            cout<<"Finished in "<<fElapsed;

コンパイルエラーは発生しません。whileループ内で構造体の変数を出力すると、問題なく出力されます...しかし、unordered_mapがいっぱいになることはありません。

4

1 に答える 1

0

上でコメントしたように、ループのすべての反復で同じハッシュhex_strバッファーが再利用されているように見えるため、毎回同じキーを使用しています(文字列の内容ではなく、ポインターアドレスがキーとして使用されています)

sha1::calcsha1::hashのシグネチャ、またはハッシュhex_strをどのように宣言したかを知らなくても、それらをそのまま正しく使用していると仮定します(c-arrayだと思います)関数はバッファーへのポインターを受け取り、出力をnullで終了しません)、私が行う最小限の変更は次のようになります。

定義:

// no typedef necessary for struct in C++
struct dictionary {
    std::string word;
    std::vector<unsigned char> hash;
    // string instead of vector so it's hashable
    std::string hex;
};
std::unordered_map<std::string, dictionary*> Mymap;

実装:

if (myfile.is_open())
{
    LARGE_INTEGER freq, before, after;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&before);
    while ( myfile.good() )
    {
        getline (myfile,line);

        dictionary * dic = new dictionary(); // after each line create
        dic->word = line;

        const char * c= line.c_str();

        dic->hash.resize(SIZE_OF_HASH_BUFFER);
        sha1::calc(c, line.length(), &(dic->hash[0]));//encrypts the word

        dic->hex.resize(SIZE_OF_HEX_STR_BUFFER);
        sha1::toHexString(&(dic->hash[0]), &(dic->hex[0]));//encrypts the word

        if(!(Mymap.insert(std::make_pair(dic->hex, dic)).second))
        {
            // handle collision somehow...
        }
    }
    QueryPerformanceCounter(&after);
    float fElapsed = static_cast<float>(after.QuadPart - before.QuadPart) / freq.QuadPart;
    cout<<"Finished in "<<fElapsed;

Mymapの使用方法によっては、辞書オブジェクトをスマートポインターでラップしたり、値で渡したりすることができます...コンテキストがないと実際には言えません。今のところ、 Mymapのコンテンツを使い終わったら、各辞書に関連付けられているメモリの割り当てを解除する必要があります...スマートポインタを使用して自動的に行うのではなく、それが本当に必要な場合は、できますが、クリーンアップには注意が必要です。

于 2013-02-27T02:40:14.253 に答える