Язык D: инициализация динамических многомерных массивов передовой практики? - PullRequest
8 голосов
/ 14 декабря 2011

Просто любопытно, если это лучший способ инициализации динамического многомерного массива в 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 ++)). </p>

Меня беспокоит это то, что он перераспределяет каждую строку массива отдельно, а не весь кусок сразу, поэтому я не знаю, приведет ли это к слишком большой перестановке памяти. Кроме того, я считаю, что он не гарантированно является смежным (так как tile - это просто массив указателей в этом случае). Есть ли «лучший» способ сделать это (который не включает использование одномерного массива и вычисление индекса самостоятельно)? Насколько я могу судить по документам, непрерывный многомерный массив может быть объявлен только с неизменяемыми измерениями во время компиляции, просто интересно, если я что-то упустил ...

Ответы [ 2 ]

17 голосов
/ 14 декабря 2011

Вы можете новый массив, по крайней мере в D2:

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

Я считаю, что это лучшая практика.

3 голосов
/ 14 декабря 2011

Вы можете выдумать это, malloc все, что вам нужно заранее

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
}

РЕДАКТИРОВАТЬ или использовать временный массив для подшивки для более чистого / менее ошибочного кода (т.е. скрыть 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
}
...