Il motivo di questo requisito è storico e poiché new type
e new type [size]
restituiscono informazioni diverse che devono essere ripulite in modo diverso.
Considerate questo codice
Foo* oneEntry = new Foo;
Foo* tenEntries = new Foo[10];
Questi entrambi restituiscono un puntatore Foo *, la differenza è la seconda chiamata si tradurrà nel costruttore Foo chiamato 10x, e che vi sia o meno 10 volte la quantità di memoria.
Quindi ora vuoi liberare i tuoi oggetti.
Per un singolo oggetto che chiamereste delete - ad es. delete oneEntry
. Ciò chiama il distruttore di oggetti e rilascia la memoria.
Ma ecco il problema: oneEntry e tenEntries sono entrambi solo punti Foo. Il compilatore non ha idea se puntano a uno, dieci o mille elementi.
Quando si utilizza la sintassi speciale di delete []
.Questo dice al compilatore "questa è una matrice di oggetti, calcola il conteggio e poi distruggili tutti".
Quello che realmente accade è che per il new type [size]
il compilatore memorizza segretamente 'la dimensione' da qualche altra parte. Quando chiami cancella [] sa che questo valore segreto esiste in modo che possa scoprire quanti oggetti ci siano in quel blocco di memoria e li distrugga.
La domanda che si potrebbe chiedere è "perché il compilatore non memorizza sempre le dimensioni?"
Questa è una grande domanda e risale agli albori del C++. C'era il desiderio che per i tipi built-in (char, int, float, ecc) quanto segue sarebbe valido per C++;
int* ptr = new int;
free(ptr);
int* ptr = (int*)malloc(sizeof(int) * someSize);
delete ptr;
Il ragionamento dietro questo era l'aspettativa che la gente avrebbe fornito le librerie che hanno restituito allocata dinamicamente la memoria, e gli utenti di queste librerie non avrebbero alcun modo di sapere se usare liberi/delete.
Questo desiderio di compatibilità significava che le dimensioni di un array non potevano essere archiviate come parte dell'array stesso e dovevano essere conservate altrove. A causa di questo sovraccarico (e ricorda, questo era nei primi anni '80) si è deciso di fare questo libro mantenendo solo gli array e non i singoli elementi. Quindi gli array hanno bisogno di una sintassi di eliminazione speciale che cerca questo valore.
La ragione per cui malloc/free non ha questo problema è che si occupano semplicemente di blocchi di memoria e non devono preoccuparsi di chiamare costruttori/distruttori.
forse è possibile aggiungere alla risposta le informazioni/i collegamenti per sovrascrivere i vari nuovi/cancella per rispondere alla domanda successiva. –
@Brian Fuori dalla curiosità: perché la necessità di distinguere tra i due? Come in, perché delete [] esiste in primo luogo? – FreeMemory