7

ファイルから取得した巨大な連続配列xfreadあります。

このチャンクを にドロップするにはどうすればよいstd::vector<>ですか? 言い換えれば、私は結果をstd::vector<>配列ではなく入れることを好みますが、結果の C++ コードは、チャンクを配列に直接ドロップするこの単純な C バージョンと同じくらい効率的であることを望んでいます。

調べてみると、placement-new を何らかの形で使用する必要があるのではないかと思いますが、呼び出しの順序と所有権の問題についてはよくわかりません。また、アライメントの問題について心配する必要はありますか?

with をテストしていますがT = unsigned、どの POD 構造体でも機能する合理的な解決策を期待しています。

using T = unsigned;
FILE* fp = fopen( outfile.c_str(), "r" );
T* x = new T[big_n];
fread( x, sizeof(T), big_n, fp );

// how do I get x into std::vector<T> v
// without calling a gazillion push_backs() or copies ?!?

delete[] x;
fclose( fp );
4

2 に答える 2

10

ベクトルのサイズを設定するstd::vector コンストラクターを使用std::vector::dataし、割り当てられたメモリへのポインターを取得するために使用します。

の使用を維持するfread:

std::vector<T> x(big_n);
fread(x.data(), sizeof(T), big_n, fp);

他の人が指摘したように、タイプがPODタイプでないfread場合に使用すると、おそらく機能しません。その後、C++ ストリームを使用して、ファイルをベクターに読み込むことができます。ただし、これにはファイル内のすべてのアイテムをループするという欠点があり、見た目ほど大きい場合、パフォーマンスの問題になる可能性があります。Tstd::istreambuf_iteratorbig_n


ただし、ファイルが本当に大きい場合は、メモリ マッピングを使用してファイルを読み取ることをお勧めします。

于 2013-01-17T13:38:57.273 に答える
0

これは、ファイルをベクトルに読み込みます

#include <vector>
#include <fstream>
#include<iterator>
// ...

std::ifstream testFile("testfile", std::ios::binary);
std::vector<unsigned char> fileContents((std::istreambuf_iterator<unsigned char>(testFile)),
                           std::istreambuf_iterator<unsigned char>());

この回答は以前の回答からのものです: https://stackoverflow.com/a/4761779/942596

于 2013-01-17T13:53:47.393 に答える