2014-07-14 8 views
5

La funzione di allocazione tenta di allocare la quantità richiesta di memoria . Se ha esito positivo, restituisce l'indirizzo di inizio di un blocco di memoria la cui lunghezza in byte deve essere almeno grande come la dimensione richiesta.Indirizzo della memoria del blocco iniziale

Che cosa significa questo vincolo? Potresti avere un esempio che viola?

Sembra, la mia domanda non è chiara. UPD: Perché "almeno"? Qual è il punto di allocazione più della dimensione richiesta? Potresti avere un esempio adatto?

+3

leggi questo: http://stackoverflow.com/questions/15604411/memory-allocation-deallocation –

+0

L'unico "vincolo" che vedo è il caso di "se ha successo", e non vedo nulla che " viola". Ti interessa espandere quello che intendi? –

+0

@MatsPetersson Vedi la mia domanda aggiornata –

risposta

5

L'assegno per l'assegnazione delle "più di quanto richiesto" è lì per consentire:

  1. buon allineamento del prossimo blocco di dati.
  2. Ridurre le restrizioni su quali piattaforme sono in grado di eseguire codice compilato da C e C++.
  3. Flessibilità nella progettazione della funzionalità di allocazione della memoria.

Un esempio di punto uno è:

char *p1 = new char[1]; 
    int *p2 = new int[1]; 

Se allochiamo esattamente 1 byte all'indirizzo 0x1000 per la prima assegnazione, e seguire che esattamente con una seconda assegnazione di 4 byte per un int, la int inizierà all'indirizzo 0x1001. Questo è "valido" su alcune architetture, ma spesso porta a un "carico più lento del valore", su altre architetture causerà direttamente un crash, perché un int non è accessibile su un indirizzo che non è un multiplo pari di 4. Poiché l'architettura sottostante di new in realtà non sa a cosa servirà la memoria, è meglio assegnarla a "l'allineamento più alto", che nella maggior parte delle architetture significa 8 o 16 byte. (Se la memoria viene utilizzata ad esempio per memorizzare i dati SSE, sarà necessario un allineamento di 16 byte)

Il secondo caso sarebbe dove "i puntatori possono solo indicare interi blocchi di parole a 32 bit". Ci sono state architetture del genere in passato. In questo caso, anche se ignoriamo il problema precedente con l'allineamento, la posizione di memoria specificata da un puntatore generico è composta da due parti, una per l'indirizzo effettivo e una per il "quale byte all'interno di quella parola".Nell'allocatore di memoria, poiché le allocazioni tipiche sono molto più grandi di un singolo byte, decidiamo di utilizzare solo il puntatore "parola completa", quindi tutte le allocazioni sono progettate sempre arrotondate alle parole intere.

Il terzo caso, ad esempio, consisterebbe nell'utilizzare un allocatore "blocco a dimensioni prefissate". Alcuni sistemi operativi in ​​tempo reale, per esempio, avranno un numero fisso di dimensioni predefinite da allocare, ad esempio 16, 32, 64, 256, 1024, 16384, 65536, 1M, 16M byte. Le allocazioni vengono quindi arrotondate alla dimensione uguale o superiore più vicina, pertanto un'allocazione per 257 byte verrà allocata dalla dimensione 1024. L'idea qui è di a) fornire un'allocazione rapida, tenendo traccia dei blocchi liberi in ogni dimensione, piuttosto che il modello tradizionale di avere un gran numero di blocchi di qualsiasi dimensione per cercare attraverso per vedere se c'è un blocco abbastanza grande. Aiuta anche contro la frammentazione (quando molta memoria è "libera", ma la dimensione sbagliata, quindi non può essere utilizzata - ad esempio, se si esegue un ciclo fino a quando il sistema non ha memoria che alloca blocchi di 64 byte, quindi libero a vicenda, e proviamo ad allocare un blocco da 128 byte, non esiste un singolo blocco da 128 byte, perché TUTTA la memoria è scolpita in piccole sezioni da 64 byte).

4

Significa che la funzione di allocazione deve restituire un indirizzo di un blocco di memoria la cui dimensione è pari almeno alla dimensione richiesta.
La maggior parte delle funzioni di allocazione, però, deve restituire un indirizzo di un blocco di memoria la cui dimensione è grande di quello che avete richiesto e le prossime assegnazioni torneranno un indirizzo all'interno questo blocco fino a raggiungere la fine di esso.
Le principali ragioni di questo comportamento sono:

  1. minimizzare il numero di nuove allocazioni blocco di memoria (ogni blocco può contenere diverse assegnazioni), che sono costosi in termini di tempo complessità.
  2. Problemi di allineamento specifici.
+0

Potresti vedere la mia domanda aggiornata? –

+0

@ St.Antario Posso vederlo ora. – eladm26

+0

@Mark Perché sei tornato alla revisione 1? Sai che contiene errori di grammatica, vero? – edmz

3

Le due ragioni più comuni per cui l'allocazione
restituisce un blocco più grande di richieste è

  1. Allineamento
  2. Contabilità
2

Può essere tale perché nei sistemi operativi moderni è molto più efficace allocare la pagina di memoria che può essere di 512 kb. Quindi la funzionalità malloc interna può solo allocare questa pagina di memoria, riempire il suo inizio con alcune informazioni di servizio in quanti blocchi secondari è diviso in, le loro dimensioni, ecc. E solo dopo che ritorna a voi un indirizzo adatto alle vostre esigenze . La prossima chiamata a malloc restituirà un'altra porzione di questa pagina allocata, per esempio. Non importa che il blocco di memoria sia limitato alle dimensioni richieste. In effetti è possibile eseguire l'overflow dell'heap di questo buffer a causa di un meccanismo sicuro per impedire questo tipo di attività. Inoltre, puoi prendere in considerazione le domande di allineamento indicate da altri risponditori sopra. Ci sono abbastanza tipi di gestione della memoria. Puoi google se sei interessato abbastanza (Best Fit, First Fit, Last Fit, correggimi se sbaglio).

Problemi correlati