2010-01-16 13 views
7

Dove posso leggere circa sbrk() in dettaglio?Come funziona sbrk() in C++?

Come funziona esattamente?

In quali situazioni vorrei utilizzare sbrk() anziché l'ingombrante malloc() e new()?

btw, qual è l'espansione per sbrk()?

risposta

8

Dai un'occhiata allo the specification for brk/sbrk.

La chiamata chiede in sostanza al sistema operativo di allocare più memoria per l'applicazione incrementando il precedente "valore di interruzione" di un determinato importo. Questa quantità (il primo parametro) è la quantità di memoria aggiuntiva che l'applicazione ottiene.

La maggior parte delle implementazioni malloc rudimentali si basano sulla chiamata del sistema sbrk per ottenere blocchi di memoria che si suddividono e tracciano. La funzione mmap è generalmente accettata come scelta migliore (motivo per cui mallocs come dlmalloc supporta entrambi con un #ifdef).

Per quanto riguarda il "come funziona", uno sbrk al suo livello più semplice potrebbe essere simile a questa:

uintptr_t current_break; // Some global variable for your application. 
         // This would probably be properly tracked by the OS for the process 
void *sbrk(intptr_t incr) 
{ 
    uintptr_t old_break = current_break; 
    current_break += incr; 
    return (void*) old_break; 
} 

I sistemi operativi moderni farebbero molto di più, come ad esempio le pagine della mappa nello spazio indirizzo e aggiungi informazioni di tracciamento per ogni blocco di memoria allocato.

+0

Si noti che le funzioni sono contrassegnate come "LEGACY" nel riferimento; se si va all'attuale specifica SUS (http://www.opengroup.org/onlinepubs/9699919799/toc.htm), questi (brk, sbrk) non sono presenti. –

+0

Buon punto: l'uso di tali funzioni può causare problemi di portabilità se un'implementazione decide di non preoccuparsi della compatibilità con le versioni precedenti. –

4

sbrk è praticamente obsoleto, in questi giorni useresti mmap per mappare alcune pagine di/dev/zero. Di certo non è qualcosa che usi al posto di malloc e amici, è più un modo di metterli in pratica. Inoltre, naturalmente, esiste solo su sistemi operativi basati su posix che si preoccupano della retrocompatibilità con il codice antico.

Se trovi che Malloc e New sono troppo ingombranti, dovresti invece cercare nella raccolta dei rifiuti ... ma attenzione, c'è un potenziale costo in termini di prestazioni, quindi devi capire cosa stai facendo.

0

Questo dipende da cosa intendi per malloc essere "ingombrante". sbrk in genere non viene più utilizzato direttamente, a meno che non si stia implementando il proprio allocatore di memoria: IE, l'operatore sovrascrive "nuovo". Anche allora potrei usare malloc per darmi la memoria iniziale.

Se desideri vedere come implementare malloc() sopra a sbrk(), controlla http://web.ics.purdue.edu/~cs354/labs/lab6/ che è un esercizio in corso.

Su un sistema moderno, questa interfaccia non deve essere toccata. Dato che chiami malloc e nuovo ingombrante, sospetto che tu non abbia tutta l'esperienza necessaria per usare sbrk in modo sicuro e appropriato per il tuo codice.

1

Non si desidera utilizzare mai sbrk anziché malloc o free. È non portatile e viene in genere utilizzato solo dagli implementatori della libreria C standard o nei casi in cui non è disponibile.E 'descritto abbastanza bene nella sua man page:

Descrizione

brk() imposta la fine del segmento di dati al valore specificato da end_data_segment, quando tale valore è ragionevole, il sistema fa avere memoria sufficiente e il processo non ha superato la dimensione massima dei dati (vedere setrlimit (2)).

sbrk() incrementa lo spazio del programma incrementandolo di byte. sbrk() non è una chiamata di sistema, è solo un wrapper della libreria C . La chiamata a sbrk() con un incremento di 0 può essere utilizzata per trovare il punto corrente dell'interruzione di programma.

Return Value

In caso di successo, brk() restituisce zero e sbrk() restituisce un puntatore l'inizio della nuova area. In caso di errore, viene restituito il valore -1 e errno è impostato su ENOMEM.

Infine, malloc e free non sono ingombranti - sono il modo standard per allocare e rilasciare la memoria in C. Anche se si desidera implementare il proprio allocatore di memoria, è meglio utilizzare solo malloc e free come base - un approccio comune è quello di allocare un grande pezzo alla volta con malloc e fornire allocazione di memoria da esso (questo è ciò suballocators, o pool, solitamente implementano)


Re l'origine del nome sbrk (o il suo cugino brk), potrebbe h ave qualcosa a che fare con il fatto che la fine dell'heap è contrassegnata da un puntatore noto come "break". L'heap inizia subito dopo i segmenti BSS e in genere cresce verso lo stack.

1

Hai codificato questo C++ quindi perché dovresti usare malloc() piuttosto ingombrante piuttosto che nuovo? In ogni caso, non sono sicuro di cosa sia complicato da Malloc; forse internamente, ma perché ti interessa? E se hai fatto attenzione (per ragioni di determinismo per esempio), potresti allocare un grande pool e implementare il tuo allocatore per quel pool. Ovviamente in C++ puoi sovraccaricare il nuovo operatore per farlo.

sbrk è utilizzato per incollare la libreria C alla gestione della memoria del sistema operativo sottostante. Quindi fai chiamate al SO piuttosto che usare sbrk(). Per quanto riguarda il suo funzionamento, dipende dal sistema. Se ad esempio si utilizza la libreria Newlib C (comunemente utilizzata sui sistemi embedded "bare metal" con il compilatore GNU), è necessario implement sbrk yourself, quindi il modo in cui funziona in tali circostanze dipende da te fino a quando raggiunge la sua richiesta comportamento dell'estensione dell'heap o del fallimento.

Come si può vedere dal link, che non fa molto e sarebbe estremamente ingombrante da usare direttamente - si sarebbe probabilmente finisce-up avvolgendolo in tutta la funzionalità che malloc e nuova forniscono in ogni caso.