L'assegno per l'assegnazione delle "più di quanto richiesto" è lì per consentire:
- buon allineamento del prossimo blocco di dati.
- Ridurre le restrizioni su quali piattaforme sono in grado di eseguire codice compilato da C e C++.
- 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).
leggi questo: http://stackoverflow.com/questions/15604411/memory-allocation-deallocation –
L'unico "vincolo" che vedo è il caso di "se ha successo", e non vedo nulla che " viola". Ti interessa espandere quello che intendi? –
@MatsPetersson Vedi la mia domanda aggiornata –