2017-01-04 28 views
-9

陣列和陣列尺寸我有一個結構:載體能夠在C++

struct xyz{ 
    int x,y,z; 
}; 

和我初始化struct xyz型載體:

for (int i = 0; i < N; i++) 
    { 
     for (int j = 0; j < N; j++) 
     { 
      for (int k = 0; k < N; k++) 
      { 
       v.x=i; 
       v.y=j; 
       v.z=k; 
       vect.push_back(v); 
      } 
     } 
    } 

然後我想的是向量變換到數組,因爲陣列是比矢量操作快2倍,所以我做

xyz arr[vect.size()]; 
std::copy(vect.begin(), vect.end(), arr); 

當我運行這個程序時,它顯示我的段我認爲是因爲vect.size()太大而引起的故障。 所以我想知道有沒有什麼辦法可以將那個大尺寸的矢量轉換成沒有這個問題的數組。 我欣賞任何幫助

+0

您需要使用堆('new'),因爲矢量的大小直到運行時才知道。 – AndyG

+13

你在哪裏得到*因爲數組比處理*的矢量快2倍?正確使用的矢量在速度方面應該與數組幾乎相同。 – NathanOliver

+3

1)VLAs('xyz arr [vect.size()];')是非標準的C++ 2)你認爲?你是否嘗試用_anything_來自己解決問題(例如調試器)? 3)_I想要將該向量轉換爲數組,因爲數組比處理向量快2倍。您在哪裏讀過這些廢話? –

回答

0

我過於迂腐的評論太大了,所以我會盡量讓這個有點迂迴的答案。簡短的答案可能只是堅持vector,但一定要使用reserve;哦,和基準。

你沒有說你正在使用什麼編譯器或C++版本,所以我只會去我當前gcc.godbolt.org默認的gcc 4.9.2,C++ 14。我也假設你真的希望這是一維數組,而不是更自然(例如)3.

如果你知道在編譯時N,你可以做這樣的事情(假設我得到了陣列偏移計算正確):

#include <array> 
... 
std::array<xyz, N*N*N> xyzs; 
for (int i = 0; i < N; i++) { 
    for (int j = 0; j < N; j++) { 
    for (int k = 0; k < N; k++) { 
     xyzs[i*N*N+j*N+k] = {i, j, k}; 
    } 
    } 
} 

最大缺點,IMO:

  • 容易出錯的偏移計算
  • 取決於N,在碼我的磨合,等,這可以吹堆棧

在我上嘗試這樣的編譯器,優化器似乎明白,我們正在通過在連續的順序在陣列移動,並將所生成的機器代碼是比較明智​​的,但它也可以寫像這樣,如果你喜歡:

#include <array> 
... 
std::array<xyz, N*N*N> xyzs; 
auto p = xyzs.data(); 
for (int i = 0; i < N; ++i) { 
    for (int j = 0; j < N; ++j) { 
    for (int k = 0; k < N; ++k) { 
     (*p++) = {i, j, k}; 
    } 
    } 
} 

當然,如果你真的在編譯時知道N,也不會吹堆棧,你可能會考慮一個3維數組xyz xyzs[N][N][N];因爲這些東西最終被使用的方式可能更自然。

正如在註釋中指出的那樣,變長數組不是合法的C++,但它們在C99中是合法的;如果你在編譯時不知道N,你應該從堆中分配。

A vector和一個數組將結束在內存佈局方面相同;它們的區別在於vector從堆中分配內存,並且數組(當您正在寫它時)將在堆棧中。我會做的唯一建議是輸入您的循環之前調用reserve

vect.reserve(N*N*N); 

這意味着你只能在前面做一個單一的內存分配,而不是成長和複製的機制,你會從默認構建的vector獲得。

假設xyz的聲明在這裏就是這麼簡單,你也可以做類似上面的第二個例子:

std::vector<xyz> xyzs{N*N*N}; 
auto p = xyzs.data(); 
for (int i = 0; i < N; ++i) { 
    for (int j = 0; j < N; ++j) { 
    for (int k = 0; k < N; ++k) { 
     (*p++) = {i, j, k}; 
    } 
    } 
} 

你失去的push_back安全,效率較低,如果xyz默認的構造函數需要做任何事情(如果xyz成員被更改爲具有默認值)。

說了這麼多,你真的應該做基準。但是,你可能應該對最終使用這個數組的代碼進行基準測試,而不是代碼來構建它;如果施工占主導地位,我還會有其他擔憂。