2011-07-27 112 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字節對齊,它可能會崩潰,做計算錯誤或只是工作緩慢(根據您的平臺)
  • (我相信有一些原因吧不工作)

不管怎麼說,這是描述作爲標準的「未定義行爲」,嚴格來說,如果您使用此解決方案,可能會發生任何事情。

相關問題