2011-12-14 108 views
8

只是好奇,如果這是初始化動態,多維數組D最佳做法。在他們的語言參考中有一個關於數組的部分,但我不太確定它是否能夠完成我想要完成的任務。D語言:初始化動態多維數組最佳實踐?

class Map { 
    Tile[][] tiles; 

    this(uint width, uint height) { 
     tiles.length = height; 
     foreach (ref tilerow; tiles) 
      tilerow.length = width; 
    } 
} 

Map map1 = new Map(5000, 3000); // values determined at runtime 

(或類似的典型爲(Y = 0的等效替代; Y <高度; Y ++)循環)。

我的這個擔心的是,它重新分配陣列分開,而不是整個數據塊中的每一行一次性全部,所以我不知道這是否會導致過多的內存洗牌。此外,我相信它不保證是連續的(因爲瓷磚只是在這種情況下的指針數組)。有沒有更好的方式來做到這一點(不涉及使用一維數組並自己計算索引)?據我可以告訴從文檔一個連續的多維數組只能在編譯時聲明與不可變尺寸,只是想知道如果我失去了一些東西...

回答

17

你可以陣列,至少在D2:

Tile[][] tiles = new Tile[][](height, width); 

我相信這是最好的做法。

3

你可以把它捏造malloc ing你需要的每一件事前期

this(uint width, uint height) { 
    void* p = enforce(GC.malloc(Tile.sizeof*width*height),new OutOfMemoryException); 
      //allocate all rows at once, throw on returned null 
    tiles.length = height; 
    foreach (i,ref tilerow; tiles) 
     tilerow = cast(Tile[])p[Tile.sizeof*width*i..Tile.sizeof*width*(i+1)]; 
       //slice it into the multidimensional array 
} 

EDIT或使用臨時數組,以保持在下襬用於清潔/更少bugprone代碼(即隱藏的malloc)

this(uint width, uint height) { 
    Tile[] p = new Tile[height*width] 
    tiles.length = height; 
    foreach (i,ref tilerow; tiles) 
     tilerow = p[width*i..width*(i+1)]; 
       //slice it into the multidimensional array 
} 
+0

+1 - 我沒有想到這個! :)謝謝你的提示! – DejanLekic 2011-12-14 11:43:47

+1

第一個示例的小記:您可以使用enforceEx,例如`executeceEx!OutOfMemoryError(GC.malloc(Tile.sizeof * width * height));`,它也不是`OutOfMemoryException`,而是`OutOfMemoryError`,這些需要導入到`std.exception`,`core.memory`和`core.exception`。 – 2011-12-14 15:30:52