2014-12-18 4 views
5

Ultimamente ho letto molto su Ruggine, ma sto ancora iniziando a ossidare. Il mio cervello conserva la maggior parte dei suoi riflessi C/C++ quindi scusami se questa domanda non è rilevante a causa di come vengono fatte le cose in Rust.Come partizionare e utilizzare la memoria heap allocata in massa con Rust?

È generalmente possibile (desiderabile?) Allocare un blocco di una dimensione arbitraria sull'heap e quindi eseguire il mapping di una struttura di dati su di esso con associazioni che assumono la proprietà di blocchi di memoria più piccoli?

Utilizzando C99, si può scrivere questo:

typedef unsigned char BYTE; 

typedef struct { 
    size_t size; 
    BYTE payload[]; 
} flex; 

// ... 

flex * flex_new(size_t _size) { 
    flex *f = malloc(sizeof(flex) + _size * sizeof(BYTE)); 
    f->size = _size; 
    return f; 
} 

array lunghezza flessibili possono risultare utili per esempio quando si implementano i pool di memoria con blocchi di dimensioni variabili o quando si alloca memoria nell'heap dedicato a un thread. La struttura dei dati che richiedeva la dimensione è nota solo al runtime e viene allocata in modo "atomico" e i suoi membri vengono compressi in modo contiguo.

Mi chiedo se una simile implementazione di Rust sia possibile (senza i costrutti unsafe) e se lo è, come appare. Forse il compilatore può dedurre alcune informazioni utilizzando gli identificatori di durata nella definizione struct?

+2

Probabilmente ci sono buoni usi, ma se è così, probabilmente stanno usando "non sicuri". Non aiuta che molte librerie che ci si aspetterebbe stiano facendo questo in realtà ha trovato diversi modi: 'Vec' è un' (ptr, length, capacity) 'triple piuttosto che un puntatore a' (length, capacity, items) ' e 'Arena' su' Vec's che non vengono mai ridimensionate. – delnan

+1

Non ero a conoscenza di 'Arena' e lo esaminerò subito, grazie! Avrei dovuto affermare che non mi interessa se "non sicuro" viene utilizzato finché un'interfaccia sicura viene fornita in "std" o come candidato per esso. – dummydev

+1

@delnan sembra doverlo aggiungere come risposta.^_^ – Shepmaster

risposta

2

In termini di 'matrici di lunghezza flessibili,' è possibile utilizzare Vec::with_capacity di allocare più di quanto il tuo bisogno immediato:

let mut vec: Vec<int> = Vec::with_capacity(10); 

// The vector contains no items, even though it has capacity for more 
assert_eq!(vec.len(), 0); 

// These are all done without reallocating... 
for i in range(0i, 10) { 
    vec.push(i); 
} 

// ...but this may make the vector reallocate 
vec.push(11); 

Per il caso più generale, TypedArena è quello che ci si vuole utilizzare, però.

+0

il collegamento per Arena sembra rotto – tafia