delete vs. delete [] operator di C ++


135

Apa perbedaan antara deletedan delete[]operator di C ++?


Anda mungkin menemukan pertanyaan ini relevan stackoverflow.com/questions/1913343/…
sharptooth

7
Masalah dengan hapus dan hapus [] adalah salah satu alasan mengapa saya suka smart pointer, dan menggunakan vector<>bukannya array kapan pun saya bisa.
David Thornley


@ Davidvidhorn Jika Anda menggunakan pointer pintar Anda masih perlu tahu perbedaan dalam arti bahwa Anda masih perlu tahu untuk tidak menulis misalnya std::unique_ptr<int>(new int[3]), karena akan memanggil reguler deletepada array yang merupakan perilaku yang tidak terdefinisi. Sebagai gantinya Anda perlu menggunakanstd::unique_ptr<int[]>
Arthur Tacca

Jawaban:


150

The deleteOperator deallocates memori dan memanggil destructor untuk satu objek yang dibuat dengan new.

The delete []Operator deallocates memori dan panggilan destructors untuk array obyek dibuat dengan new [].

Menggunakan deletepada pointer yang dikembalikan oleh new []atau delete []pada pointer yang dikembalikan oleh newhasil dalam perilaku yang tidak ditentukan.


3
Saya bertanya-tanya apakah menggunakan delete pada array [] baru tipe primitif seperti int atau char (tidak ada konstruktor / destruktor) tentu mengarah pada perilaku yang tidak terdefinisi juga. Tampaknya ukuran array tidak disimpan di mana pun saat menggunakan tipe primitif.
thomiel

21
Jika standar tidak menentukan apa yang terjadi ketika itu dilakukan, itu adalah definisi "perilaku tidak terdefinisi", bahkan jika kompiler Anda secara deterministik melakukan apa yang Anda inginkan. Kompiler lain mungkin melakukan sesuatu yang sama sekali berbeda.
Rob K

Saya membuat kesalahan ini ketika saya memiliki array string C seperti "char ** strArray". Jika Anda memiliki array seperti yang saya lakukan, Anda perlu mengulangi melalui array dan menghapus / membebaskan setiap elemen, kemudian menghapus / membebaskan strArray itu sendiri. Menggunakan "delete []" pada array yang saya miliki tidak berfungsi sejak (seperti yang ditunjukkan oleh komentar dan jawaban di atas), IT PANGGILAN DESTRUKTOR, itu tidak benar-benar membebaskan setiap slot.
Katianie

88

The delete[]operator yang digunakan untuk array hapus. The deleteoperator yang digunakan untuk menghapus objek non-array. Itu panggilan operator delete[]dan operator deletefungsi masing-masing untuk menghapus memori bahwa array atau objek non-array ditempati setelah (akhirnya) memanggil destruktor untuk elemen-elemen array atau objek non-array.

Berikut ini menunjukkan hubungan:

typedef int array_type[1];

// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;

// create and destroy an int
int *b = new int;
delete b;

// create and destroy an int[1]
int *c = new int[1];
delete[] c;

// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;

Untuk newyang menciptakan array (jadi, apakah itu new type[]atau newditerapkan pada konstruksi tipe array), Standar mencari sebuah operator new[]di kelas tipe elemen array atau dalam lingkup global, dan melewati jumlah memori yang diminta. Mungkin meminta lebih dari N * sizeof(ElementType)jika ia ingin (misalnya untuk menyimpan jumlah elemen, jadi nanti ketika menghapus tahu berapa banyak panggilan destruktor yang harus dilakukan). Jika kelas menyatakan operator new[]bahwa tambahan untuk jumlah memori menerima yang lain size_t, parameter kedua itu akan menerima jumlah elemen yang dialokasikan - ia dapat menggunakan ini untuk tujuan apa pun yang diinginkan (debugging, dll ...).

Untuk newyang membuat objek non-array, ia akan mencari operator newdi dalam elemen elemen atau dalam lingkup global. Itu melewati jumlah memori yang diminta ( sizeof(T)selalu selalu).

Untuk delete[]itu, ia melihat ke tipe kelas elemen array dan memanggil destruktor mereka. The operator delete[]fungsi yang digunakan adalah satu di kelas jenis elemen, atau jika tidak ada maka dalam lingkup global.

Untuk delete, jika pointer yang lewat adalah kelas dasar dari jenis objek yang sebenarnya, kelas dasar harus memiliki destruktor virtual (jika tidak, perilaku tidak terdefinisi). Jika itu bukan kelas dasar, maka destruktor dari kelas itu disebut, dan operator deletedi kelas itu atau global operator deletedigunakan. Jika kelas dasar disahkan, maka destruktor tipe objek aktual disebut, dan operator deleteditemukan di kelas itu digunakan, atau jika tidak ada, global operator deletedisebut. Jika operator deletedi dalam kelas memiliki parameter tipe kedua size_t, ia akan menerima jumlah elemen untuk dialokasikan ulang.


18

Ini penggunaan dasar pola mengalokasikan / DE mengalokasikan dalam c ++ malloc/ free, new/ delete, new[]/delete[]

Kita harus menggunakannya secara bersamaan. Tetapi saya ingin menambahkan pemahaman khusus ini untuk perbedaan antara deletedandelete[]

1) deletedigunakan untuk mengalokasikan memori yang dialokasikan untuk objek tunggal

2) delete[]digunakan untuk mengalokasikan memori yang dialokasikan untuk berbagai objek

class ABC{}

ABC *ptr = new ABC[100]

ketika kita mengatakan new ABC[100], compiler dapat memperoleh informasi tentang berapa banyak objek yang perlu dialokasikan (ini adalah 100) dan akan memanggil konstruktor untuk setiap objek yang dibuat

tetapi sesuai dengan itu jika kita hanya menggunakan delete ptruntuk kasus ini, kompiler tidak akan tahu berapa banyak objek yang ptrmenunjuk dan akan berakhir memanggil destruktor dan menghapus memori hanya untuk 1 objek (meninggalkan permintaan destruktor dan deallokasi 99 objek yang tersisa). Karenanya akan ada kebocoran memori.

jadi kita perlu menggunakan delete [] ptrdalam hal ini.


3
Ini seharusnya jawaban yang benar. Tidak ada jawaban lain yang menyebutkan perbedaan yang jelas: "tetapi jika kita hanya menggunakan delete ptr untuk kasus ini, kompiler tidak akan tahu berapa banyak objek yang menunjuk ke ptr dan akan berakhir memanggil destructor dan menghapus memori hanya untuk 1 objek"
Don Larynx

1
Bagaimana kita mencapai hal yang sama di C?
Dogus Ural

@DogusUral Kenapa? Tidak ada destruktor di C, jadi Anda hanya free()ini dan itu. Jika Anda menggunakan pola pseudo-destructor, Anda harus memanggilnya sekali untuk setiap objek menggunakan forloop.
Kotauskas

@ DonLarynx perbedaan yang benar adalah bahwa mencampurkannya menghasilkan program yang salah bentuk. Sebuah implementasi mungkin tahu berapa banyak objek yang akan dihancurkan, atau mungkin tidak . Diijinkan untuk mengetahui bahwa itu disebut salah, dan batalkan program yang memberi tahu Anda di mana masalahnya.
Caleth

6

Operator deletedan delete []digunakan masing-masing untuk menghancurkan objek yang dibuat dengan newdan new[], kembali ke memori yang dialokasikan tersisa yang tersedia untuk manajer memori kompiler.

Objek yang dibuat dengan newharus dihancurkan delete, dan array yang dibuat dengan itu new[]harus dihapus delete[].


2

Ketika saya mengajukan pertanyaan ini, pertanyaan saya yang sebenarnya adalah, "apakah ada perbedaan di antara keduanya? Tidakkah runtime harus menyimpan informasi tentang ukuran array, dan apakah itu tidak dapat menentukan yang mana yang kami maksud?" Pertanyaan ini tidak muncul dalam "pertanyaan terkait", jadi hanya untuk membantu orang-orang seperti saya, inilah jawabannya: "mengapa kita bahkan perlu operator hapus []?"


Terima kasih telah kembali dan memasukkan ini.
Ziffusion

0

deletedigunakan untuk satu pointer tunggal dan delete[]digunakan untuk menghapus array melalui sebuah pointer. Ini mungkin membantu Anda untuk memahami dengan lebih baik.


-6

Yah .. mungkin saya pikir itu hanya untuk eksplisit. Operator deletedan operator delete[]dibedakan tetapi deleteoperator dapat melepaskan array juga.

test* a = new test[100];
delete a;

Dan sudah diperiksa kode ini tidak ada kebocoran memeory.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.