2015-09-01 142 views
10

按照Rust Reference32位數組的最大大小?

isize類型是有符號整數類型具有相同數目的比特作爲平臺的指針類型。對象和數組大小的理論上限是最大isize值。這確保isize可用於計算指向對象或數組的指針之間的差異,並且可以處理對象中的每個字節以及超過結尾的一個字節。

這明顯地限制了一個數組在32位系統上的最多2G元素,但是不清楚的是數組是否也被約束到最多2GB的內存。

在C或C++中,您可以將指向第一個和最後一個元素的指針轉換爲char*,並獲取這兩個指針的差異;有效地將陣列限制爲2GB(以免溢出intptr_t)。

32位數組是否也限制在2GB的Rust中?或不?

回答

5

Vec的的內部不封頂的值到4GB,無論是在with_capacitygrow_capacity,使用

let size = capacity.checked_mul(mem::size_of::<T>()) 
        .expect("capacity overflow"); 

這將恐慌如果指針溢出。

因此,Vec-分配的切片也以這種方式在Rust中加蓋。鑑於這是由於分配API的基本限制,如果任何典型的類型可以繞過這一點,我會感到驚訝。如果他們這樣做,片上的Index由於指針溢出而不安全。所以我希望不會。

儘管如此,仍然不可能爲所有4GB分配其他原因。特別是,allocate不會讓你分配超過2GB(isize::MAX字節),所以Vec僅限於此。

+0

所以答案是:是的,這僅限於2GB? –

+0

@MatthieuM。是。我已經編輯了我的答案,對此有點更清楚。 – Veedrac

+1

'capacity'在兩種方法中都是'usize',所以'Vec'的最大容量爲4GB。但是,如果請求的分配大小超過2GB,則分配器可能會失敗... –

2

Rust使用LLVM作爲編譯器後端。指針運算的LLVM指令(GetElementPtr)採用帶符號的整數偏移量,並且在溢出時具有未定義的行爲,因此在針對32位平臺時,無法將大於2GB的數組索引到索引中。

爲了避免未定義的行爲,Rust會拒絕在單個分配中分配超過2 GB的內存。有關詳細信息,請參閱Rust問題#18726

+1

我檢查了錯誤和GEP常見問題,限制不是內存問題,而是元素數量:當您將'i32 1'傳遞給GEP時,它會逐步增加1個元素,因此可以使用4個字節元素4 GB數組很容易。請注意,該示例具體是關於'Vec '這是一個1字節的元素,因此該示例的限制爲2GB。 –