2011-12-14 112 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