16

In C++, se si vuole allocare dinamicamente un array, si può fare qualcosa di simile:Perché il compilatore richiede `delete [] p` versus` delete p [] `?

int *p; 
p = new int[i]; // i is some number 

Tuttavia, per cancellare la matrice, che fai ...

delete[] p; 

Perché isn' t it delete p[]? Non sarebbe più simmetrico con il modo in cui è stato originariamente creato? Qual è il motivo (se esiste) del perché il linguaggio è stato progettato in questo modo?

+8

Perché il downvote/votare per chiudere? Cosa posso fare per migliorare la domanda? – Michael0x2a

+5

@Deflect: era mio, di solito 'perché è stato scelto questo costrutto linguistico?' le domande non sono semplicemente costruttive perché non c'è una risposta obiettiva e ragionevole. Tuttavia, in questo caso ci sono alcune ragioni decenti, quindi potrei aver giudicato troppo presto (ho rimosso il mio downvote abbastanza velocemente). – KillianDS

+1

@ KillianDS: Ok, questo ha senso. Grazie per la risposta! [e rassicurandomi che non sono del tutto fuori base :)] – Michael0x2a

risposta

29

Una ragione potrebbe essere quella di rendere questi casi più distinti.

int ** p; 
delete[] p 
delete p[1]; 

Se fosse delete p[] poi un errore di un carattere avrebbe consquences abbastanza brutto.

+13

Questo è particolarmente vero, in quanto all'inizio del C++, dovevi specificare il numero di elementi in '[]'. –

+4

@JamesKanze: Sembra che sia la risposta per me. 'delete p [4]' sarebbe ambiguo. – GManNickG

+0

@GManNickG Esattamente. –

2

Poiché l'array decade per puntare quando passa come parametro alla funzione (o all'operatore). Quindi eliminare p [] sarebbe semplicemente equivalente a eliminare p.

[modifica] Possiamo pensare di eliminazione come dell'operatore modello speciale. L'operatore dovrebbe essere in grado di distinguere tra p e p [] per scegliere la "specializzazione" giusta (eliminazione di array o array). Tuttavia, le regole di deduzione degli argomenti del modello rendono impossibile questa scelta (a causa del decadimento dell'array non possiamo distinguere tra p [] e p quando deduciamo l'argomento).

Quindi non possiamo usare all'operatore nome eliminare sia per casees e la necessità di introdurre un altro operatore delete [] con nome differente (suffisso [] può essere trattata come parte del nome dell'operatore) per caso array.

[modifica 2] Nota. delete p [] non è affatto una sintassi valida secondo lo standard corrente. Il ragionamento qui sopra mostra solo problemi che potrebbero emergere se provassimo a interpretare delete p [] usando concetti C++ esistenti.

+0

No, non è equivalente. Usarne uno al posto di un altro è un comportamento indefinito. – sharptooth

+0

@sharptooth:? passare un array in una funzione basata su modelli invece che su un puntatore è UB? Penso all'eliminazione dell'operatore basato su modelli e questo operatore non può scegliere la specializzazione giusta perché non può distinguere tra p [] e p quando deduce l'argomento.Quindi abbiamo bisogno di introdurre un operatore speciale delete [] per gli array invece di usare lo stesso nome operatore – user396672

+0

Il passaggio di un puntatore restituito da 'new' a' delete [] 'è UB – sharptooth