2017-02-16 22 views
3

在C++中,我感到非常不方便,因爲C++沒有內置功能在運行時爲多維數組動態分配內存。爲什麼C++沒有一種方便的方式爲多維數組動態分配內存?

在Java中,我們可以通過一行代碼來完成。例如,在Java中,我們可以動態分配內存四維整數數組

int a, b, c, d; 
std::cin>>a>>b>>c>>d; 
int[ ][ ][ ][ ] array = new int[a][b][c][d]; 

我用Google搜索的解決方案,以做同樣的事情在C++中。但我發現,在C++中,我們必須使用嵌套的循環,容器或一些具有函數的結構來實現相同的功能。既然這樣的語法功能會非常方便,我想問問爲什麼C++沒有包含這樣的內置功能?

+3

有趣有趣的事實:即四維陣列中的Java?它不是一個4D陣列。它是由整數數組組成的數組數組。由於每個動態分配的子數組之間沒有連接,因此可能會非常緩慢。 CPU從一個分配跳轉到下一個分配,並且從未從所有預加載到緩存中的連續數據中獲取速度。可怕的嵌套循環C++解決方案做同樣的事情,它是可怕的。除非你需要鋸齒狀的數組,否則不要用任何一種語言來完成。圍繞處理索引的一維數組進行封裝。 – user4581301

+0

下面是一個示例:https://isocpp.org/wiki/faq/operator-overloading#matrix-subscript-op – user4581301

回答

9

在C++中,你也可以這樣分配內存。例如:)

auto array = new int[3][4][5][6]; 

,或者是相同的

int (*array)[4][5][6] = new int[3][4][5][6]; 

或者你可以使用一個typedef像

typedef int T[4][5][6]; 
// or 
// using T = int[4][5][6]; 

T *array = new T[3]; 

的問題是,在廣場的表情,除了最左邊的絕是不變的表達。

+0

另一個問題是它有泄漏內存的傾向,例如,當您以不同尋常的方式退出時 – sp2danny

+0

謝謝!我忘了我們可以使用自動。所以這裏的自動類型將和int * array [] [] []一樣?你的回答非常有幫助!但有沒有辦法通過在運行時使用非常量表達式來實現這一點?大多數時候,我不需要使用多維數組。但我決定很好地學習C++,並想知道更多關於它的細節。因此,我的第二個問題是什麼上下文適合使用多維數組?我們是否總是需要避免它們? –

+0

@HanM查看我更新的帖子。我展示了另外的聲明。不幸的是表達式必須是不變的。因此,在編譯時不知道元素的數量時,通常使用標準容器,如C++中的std :: vector。 –

1

我們也可以創建大小的2D矩形陣列(M,N)作爲

auto array = (int (*)[N]) new int [ M*N ]; 

和尺寸(L,M,N)的作爲

auto array = (int (*)[M][N]) new int [ L*M*N ]; 

等三維陣列(其中L,M,N,...可以是變量)。爲此定義一個宏可能很方便。另外,如果尺寸小,我們可以簡單地做作爲

int array[M][N]; 

(我在此之前,從#1瞭解到,感謝了!)的

+0

「int array [M] [N]」不必擔心泄漏,因爲它被分配到堆棧上(正確?),但是使用原始的「新」和指針有泄漏風險;所以我認爲使用一些現有的容器類或快速庫來實現多暗度陣列(特別是用於數值計算)會更好(更安全)。 – roygvib

+0

謝謝!我是C++新手,不確定(int(*)[N])和(int(*)[M] [N])的含義。他們看起來像類型。但我不確定如何正確理解它們。它們看起來也像通用表達式。 –

+0

@HanM嗨,它並不是什麼特別的東西,它只是將類型轉換爲指向矩形數組的指針(參見上面的Vlad的第二個例子)。如果你找到一些更好的方法多暗淡陣列,請讓我知道:) – roygvib

2

首先,千萬不要用new。一切都有更好的選擇。

步驟零,適當的包括

#include <gsl/multi_span> 
#include <memory> 

步驟一設置尺寸,

constexpr int x_sz = 3; 
constexpr int y_sz = 4; 
constexpr int z_sz = 5; 
constexpr int total = x_sz * y_sz * z_sz; 

第二步,分配存儲器

auto arrptr = std::make_unique<int[]>(total); 

第三步,創建一個數組視圖

gsl::multi_span<int, x_sz, y_sz, z_sz> arr3d { arrptr.get(), total }; 

恭喜你,你有一個邊界檢查的三維數組 ,當它超出範圍時會自行釋放它。

你可以找到GSL here

+0

謝謝! GSL還沒有完成?我計劃在完成時閱讀它。 –

相關問題