2011-07-27 14 views
2

私は、リスト内にたくさんのデータを持っています。例えば、各要素に数キロバイトなど、いくつかの数値処理を行うためにそれぞれを抽出したいと思います。これらのデータはもともとfloat []として格納されています。処理には多くの索引付けとグローバルな計算が必要なので、valarrayはプログラミングが簡単かもしれないと思います。しかし、私がvalarrayを使用する場合は、配列からvalarrayにコピーしてから配列にコピーバックする必要があります。これを避ける方法はありますか?私が直接アレイ上で動作させるような方法はありますか?あるいは、同様の問題を解決するより良い方法がありますか?valarrayと配列の間のコピーを避ける方法はありますか?

+1

実際に解決しようとしている問題は何ですか? –

+0

@tomalak:リスト内のメモリに内部的に格納されている多くのデータを処理したいだけです。リストの各要素は、データ構造またはクラスです。この処理には、主にデータ構造内の配列内のすべてまたは一部の値に対する数値計算が含まれます。今回私はそれをはっきりさせることを願っています。 – shangping

+0

私は問題を全く理解していません。おそらく私はちょうど厚いです。 –

答えて

1

valarrayタイプでは、データストアとして既存のアレイを使用する方法はありません。それは常にそれ自身のためのコピーを作る。データを通常の配列に格納する代わりに、最初からvalarrayに直接値を格納します。 v.resizeを呼び出してサイズを設定し、[]演算子で値を代入するか、&v[0]を使用して最初の値へのポインタを取得し、イテレータまたはバッファポインタと同じように使用します。valarrayの要素はメモリに連続して格納されます。

+0

ありがとう、私はあなたの言うことを理解しています。問題は、あまりにも多くの変更を伴う以前のアレイデザインを変更できないということです。 – shangping

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バイトのアライメントが、それは、クラッシュ間違った計算を行うか、単に
  • はとにかく

(私はそれが動作しないためにいくつかのより多くの理由がある確信している)、それは説明しています(ご使用のプラットフォームに応じて)ゆっくりと動作するかもしれ標準によって「未定義の振る舞い」となっているので、この解決策を使用すると何かが起こる可能性があります。

関連する問題