2

次のように、3 つの大きなバイナリ ファイル (それぞれ c.180Mb) を std::vector に読み込んでいます。

m_ifStream.open("myfile.dat", std::ios::binary | std::ios::in);

if (m_ifStream)
{
    //Obtain input stream length
    m_ifStream.seekg (0, ios::end);
    streamLength = (size_t)(m_ifStream.tellg());
    m_ifStream.seekg (0, ios::beg);

    //Reserve doesn't work around the problem, may be more efficient though...
    //m_buffer = new vector<unsigned char>();
    //m_buffer->reserve(streamLength);

    //Next line sometimes results in bad_alloc when reading a large file
    m_buffer = new vector<unsigned char>((std::istreambuf_iterator<char>(m_ifStream)), (std::istreambuf_iterator<char>()));
}

ベクターを設定するための呼び出しが失敗し、「不適切な割り当て」例外がスローされます。

最初のファイルを読み取るときに、作成に失敗することがあります。それ以外の場合は、2 番目または 3 番目に失敗します。私は Visual Studio 2010 を使用しており、コードを 32 ビットとしてコンパイルしています。これは、最大 2Gb までアドレス指定できるはずです。少なくとも 10Gb の空き容量がある 16Gb の RAM を搭載したマシンで実行しているため、使用可能なメモリの不足は問題ではありません。このエラーは、デバッグ構成とリリース構成の両方で発生します。

でメモリを事前に割り当てreserveても役に立ちません。

ベクトルのmax_sizeプロパティは 2^32 を返すため、コンテナーの制限ではないようです。

コードは、合計サイズが 180Mb を超える多数の小さなファイルで問題なく、コードが境界に達していると思います。

大きな入力ファイルからベクトルを設定する受け入れられた方法はありますか? ファイル内の各バイトを反復することを避けたかったのでistreambuf_iterator 、この種の操作には using が最適化されると考えていました。

4

3 に答える 3

0
m_buffer = new vector<unsigned char>();
m_buffer->reserve(streamLength);

//Next line sometimes results in bad_alloc when reading a large file
*m_buffer = vector<unsigned char>((std::istreambuf_iterator<char>(m_ifStream)), (std::istreambuf_iterator<char>()));

私を襲った最初のことは、既に事前に割り当てられたvector. 新しいベクターを作成してそのベクターを上書きする場合、「予約」を行う意味がないことは明らかです。これは、これらの比較的大きなベクトルの両方のためのスペースが必要であることを意味します。

m_bufferベクトルへのポインターにならないように変更することから始めます-そうすれば、呼び出す必要はありませんnew vector<unsigned char>-ベクトルへのポインターを持つことはほとんど目的を果たしません[せいぜい、あなたが持っている場合、約16バイトを節約します何も含まないベクトル]。

次に、を削除しreserveます。それがどうなるか見てください。

于 2013-10-12T19:25:18.477 に答える