2016-02-11 198 views
3

當我做到以下幾點:未處理的異常

float name[512][512][3] 

我得到這個大錯誤,使我打破。我正在使用Visual Studio。

我注意到簡單地把「靜態」放在前面導致錯誤消失,但我希望這是一個實例字段。我不知道爲什麼會發生這種情況 - 陣列不是那麼大,而且我有一臺功能強大的機器。

嘗試[512] [512]打破了我,但[256] [512]是完全沒問題的。

我在我的智慧結尾!請幫助:)

+1

待辦事項你知道'sizeof(float)* 512 * 512 * 3'需要多少內存,'static'是什麼意思? –

+0

大約3兆字節?我相信靜態把它放在堆的一部分,它可以存儲更多的數據?我不太瞭解! – Jon

+0

「陣列不是那麼大」 - 它是3MB。雖然堆內存並不多,但它對於堆棧來說是很多**。你是否創建了這種類型的局部變量?考慮使用'std :: vector '而不是數組,或動態分配實例。 – Angew

回答

5

該陣列是3  MB(在大多數實現float)。這種大小的對象應該只能動態分配,而且對於駐留在堆棧上的MB太多了。

您有兩種選擇:一種是保持您的課堂是原樣,並確保您只有動態分配(使用new,擁有智能指針)。

另一個我更喜歡使用std::vector<float>而不是3維數組,並將其作爲存取函數實現索引。您甚至可以將這個向量存儲在自己的類中,並將其用作您的name數據成員的類型。

第二個選項保證3&thinsp; MB的數據將從永不駐留在非動態內存中。


這裏有這樣的一種可能的草圖3D訪問的vector

template <class T, size_t Dim1, Dim2, Dim3> 
class Array3d 
{ 
    std::vector<T> data; 

public: 
    Array3d() : data(Dim1 * Dim2 * Dim3) {} 

    T& at(size_t idx1, size_t idx2, size_t idx3) 
    { return data[idx1 * Dim2 * Dim3 + idx2 * Dim3 + idx3); } 

    T at(size_t idx1, size_t idx2, size_t idx3) const 
    { return data[idx1 * Dim2 * Dim3 + idx2 * Dim3 + idx3); } 
}; 

一個更基本的替代方案是隻動態分配數組本身:

using Array2d = std::array<std::array<float, 3>, 512>; 
std::unique_ptr<Array2d[]> name{new Array2d[512]}; 
name[i][j][k] = 42.0f; 
+0

我們之間的Fortran黑客不會將它稱爲'at' - 我們將其稱爲'operator()'。所以用法是'array3d(i,j,k)= 42.0f;'。 –

+0

感謝您的迴應!我非常欣賞vector的代碼,但它比我的水平稍高一點,我只想堅持我理解的東西。你能提供一個動態分配3D數組的例子嗎?我試過「float * name = new float [512] [512] [3]」,無濟於事 – Jon

+0

@MartinBonner這當然是一種可能性。或者它可以定義'operator []'返回一個鏈接'[i] [j] [k]'的代理。我只是展示了原則,真的。 – Angew