リストには大量のデータがあり、たとえば各要素に数キロバイトあります。数値処理を行うために、それぞれを抽出したいと思います。これらのデータは、もともと float[] として格納されています。処理には多くのインデックスとグローバルな計算が含まれるため、valarray はプログラムしやすいのではないかと思います。しかし、valarray を使用する場合は、最初に配列から valarray にコピーしてから、配列にコピーし直す必要があります。これを回避する方法はありますか?配列で直接作業できるようにする方法はありますか? または、同様の問題を解決するためのより良い方法はありますか?
1156 次
2 に答える
1
このvalarray
型は、データストアに既存の配列を使用する方法を提供しません。常に自分自身のコピーを作成します。データを通常の配列に格納する代わりに、値を最初から直接に格納しますvalarray
。を呼び出してサイズを設定し、演算子を使用v.resize
して値を割り当てるか、を使用して最初の値へのポインターを取得し、イテレーターまたはバッファーポインターと同じように使用します。aの要素はメモリに連続して格納されます。[]
&v[0]
valarray
于 2011-07-27T17:32:56.360 に答える
1
警告: 醜いハック。
私のシステム (MS Visual Studio) では、valarray
クラスは次のように定義されています。
template<class _Ty>
class valarray
{
...
private:
_Ty *_Myptr; // current storage reserved for array
size_t _Mysize; // current length of sequence
size_t _Myres; // length of array
};
したがって、同じレイアウトを持つ独自のクラスを作成できます (十分なレベルの自信を持って)。
struct my_valarray_hack
{
void *_Myptr;
size_t num_of_elements;
size_t size_of_buffer;
};
次に、空valarray
を作成し、その内部変数を上書きして、データを指すようにします。
void do_stuff(float my_data[], size_t size)
{
valarray<float> my_valarray;
my_valarray_hack hack = {my_data, size, size};
my_valarray_hack cleanup;
assert(sizeof(my_valarray) == sizeof(hack));
// Save the contents of the object that we are fiddling with
memcpy(&cleanup, &my_valarray, sizeof(cleanup));
// Overwrite the object so it points to our array
memcpy(&my_valarray, &hack, sizeof(hack));
// Do calculations
...
// Do cleanup (otherwise, it will crash)
memcpy(&my_valarray, &cleanup, sizeof(cleanup));
// Destructor is silently invoked here
}
これは推奨される方法ではありません。必要なものを実装する方法が他にない場合にのみ検討する必要があります (そうでない場合もあります)。失敗する可能性のある考えられる理由:
- のレイアウトは
valarray
、コンパイルの別のモードでは異なる場合があります (モードの例: デバッグ/リリース、異なるプラットフォーム、異なるバージョンの標準ライブラリ) - 何らかの方法で計算のサイズを変更する
valarray
と、バッファの再割り当てが試行されてクラッシュします - の実装
valarray
がそのバッファに 16 バイトのアラインメントがあると想定している場合、クラッシュしたり、間違った計算を行ったり、動作が遅くなる可能性があります (プラットフォームによって異なります)。 - (うまくいかない理由は他にもあると思います)
とにかく、それは標準によって「未定義の動作」として記述されているため、厳密に言えば、このソリューションを使用すると何かが起こる可能性があります.
于 2013-05-08T18:11:48.607 に答える