2011-12-14 37 views
8

Chỉ cần tò mò nếu đây là phương pháp hay nhất để khởi tạo mảng động, đa chiều trong D. Có một phần về mảng trong tài liệu tham khảo ngôn ngữ của họ, nhưng tôi không hoàn toàn chắc chắn nếu nó đi qua những gì tôi đang cố gắng để thực hiện.Ngôn ngữ D: khởi tạo các phương pháp hay nhất về mảng đa chiều động?

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 

(hoặc phương án thay thế tương đương như (y = 0; y < chiều cao; y ++)).

Mối quan tâm của tôi với điều này là nó phân bổ lại từng hàng của mảng riêng biệt hơn là toàn bộ đoạn cùng một lúc, vì vậy tôi không biết liệu điều này có dẫn đến xáo trộn bộ nhớ quá nhiều hay không. Ngoài ra, tôi tin rằng nó không đảm bảo được tiếp giáp (vì gạch chỉ là một mảng con trỏ trong trường hợp này). Có cách nào "tốt hơn" để làm điều này (điều đó không liên quan đến việc sử dụng mảng đơn chiều và tự tính toán chỉ mục) không? Theo như tôi có thể nói từ các tài liệu một mảng đa chiều tiếp giáp chỉ có thể được khai báo với kích thước bất biến tại thời gian biên dịch, chỉ cần tự hỏi nếu tôi đang thiếu một cái gì đó ...

Trả lời

17

Bạn có thể new mảng, ít nhất là trong D2:

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

Tôi tin rằng đây là phương pháp hay nhất.

+2

Về mặt kỹ thuật, thực hành _best_ sẽ sử dụng 'tự động' ở phía bên trái thay vì lặp lại loại. Nhưng vâng, đây là cách tốt nhất để phân bổ một mảng đa chiều miễn là mỗi trong số chúng được cho là có cùng chiều dài. –

+0

Điều này dường như làm các trick, cảm ơn! – ccjuju

+0

Đồng thời xem [http://www.d-programming-language.org/expression.html#NewExpression](http://www.d-programming-language.org/expression.html#NewExpression). – XP1

3

bạn có thể fudge nó bởi malloc ing mọi thứ bạn cần trả trước

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 hoặc sử dụng một mảng tạm thời để giữ hem trong cho sạch đang bugprone/ít hơn (tức là ẩn 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 - Tôi không nghĩ về điều này! :) Cảm ơn gợi ý! – DejanLekic

+1

Ghi chú nhỏ cho mẫu đầu tiên: Bạn có thể sử dụng executeceEx, ví dụ: 'executeceEx! OutOfMemoryError (GC.malloc (Tile.sizeof * width * height));', nó cũng không phải là 'OutOfMemoryException', nhưng' OutOfMemoryError', và chúng yêu cầu nhập vào 'std.exception',' core.memory' và 'core.exception'. –

Các vấn đề liên quan