2013-08-04 699 views
5
int* arr = new int[count]; 

delete arr; 

Tại sao tính năng này hoạt động? Tôi đã kiểm tra và nó thực sự giải phóng bộ nhớ. Từ những gì tôi đã đọc tôi cần delete[] arr; nếu không nó sẽ không thực sự giải phóng tất cả bộ nhớ.C++ xóa bộ nhớ mảng mà không có dấu ngoặc đơn vẫn hoạt động?

+1

AFAIK đây là UB. – Borgleader

+3

"Tại sao tính năng này hoạt động?" - nó không, nó chỉ xuất hiện để được làm việc. –

+0

Nếu không có dấu ngoặc đơn, bạn đang gọi chỉ là một destructor, không phải tất cả các destructors trong mảng. Ngoài ra, hãy xem http://stackoverflow.com/questions/2425728/delete-vs-delete-operators-in-c – GreatBigBore

Trả lời

7

Bây giờ thử nó bằng cách điền thông mảng với chuỗi của mỗi 100 byte, và xem nếu nó vẫn giải phóng tất cả các cấp phát bộ nhớ ...

Đó là hành vi không xác định, và như mọi khi, đôi khi UB sẽ xuất hiện làm việc. Trong trường hợp của bạn, bạn không có destructor cho các đối tượng trong bộ nhớ, do đó, không có "làm việc thêm", chỉ cần giải phóng tất cả bộ nhớ [1]. Nhưng nếu bạn có một đối tượng có một destructor mà làm một cái gì đó hữu ích, nó (có thể) sẽ không được gọi.

Bạn nên luôn sử dụng delete [] nếu bạn đã sử dụng new T[size]; để phân bổ. Đừng trộn lẫn cả hai, nó luôn luôn sai - đôi khi nó HAPPENS hoạt động [giống như MỘT SỐ kích thước của spanners in inches hoạt động trên các hạt mm và ngược lại - nhưng vẫn sai khi sử dụng một bộ cờ lê đặt trên các hạt metric].

[1] Lưu ý rằng điều này có thể làm việc cho sự kết hợp thư viện/C++ đặc biệt này. Biên dịch nó với một trình biên dịch khác, sử dụng một thư viện C++ khác, hoặc biên dịch cho một hệ điều hành khác có thể gây ra sự cố khi bạn thử cùng một thứ.

3

xóa và xóa [] thực sự là các toán tử khác nhau và sử dụng sai toán luôn là lỗi. Vấn đề là nó thường có vẻ tốt vào thời điểm đó, nhưng heap đã bị hỏng và bạn rất có thể gặp phải một vụ tai nạn rõ ràng không liên quan sau đó.

+0

Tôi không hiểu tại sao tôi bị đánh dấu xuống vì điều này là TRUE. Bạn có thể thử chạy valgrind hoặc một công cụ phân tích bộ nhớ tương tự và nó sẽ hiển thị lỗi tham nhũng khi nó xảy ra. –

+1

Tôi hy vọng những người bình luận downvoters. Tôi quan tâm phần nào có thể không chính xác. – user2029077

+0

Tôi không biết tại sao- đây là câu trả lời hoàn toàn chính xác. – Puppy

6

Sự khác biệt không phải là có hay không cấp phát bộ nhớ được giải phóng đúng - cho dù bạn sử dụng

delete 

hoặc

delete[] 

bộ nhớ vẫn sẽ được deallocated đúng cách.

Sự khác biệt là liệu các trình phá hủy có được gọi đúng cách hay không.

delete // will only invoke the destructor of the first element of the array. 

delete[] // will invoke the destructor for *each* element of the array. 

Điều này không có hiệu quả thiết thực cho các kiểu nguyên thủy như int hoặc float, nhưng khi bạn có một số lớp, sự khác biệt có thể rất quan trọng.

+0

Tôi có thể tưởng tượng một triển khai thực hiện điều này là đúng. Bạn có tài liệu thực tế về việc triển khai cho thấy điều này đúng không? – sehe

+2

Không có tài liệu, chỉ có kinh nghiệm của riêng tôi trong này là với Visual C++. Đã một thời gian, nhưng tôi nhớ phải đối mặt với lỗi vì tôi sử dụng sai xóa thay vì xóa []. Khá chắc chắn rằng nó hoạt động như tôi đã mô tả ... hãy nhớ rằng * x dereferences cùng một vị trí như x [0], và tuyên bố x như một con trỏ đến bất cứ điều gì nói gì về việc đối tượng mục tiêu là vô hướng hay mảng, do đó, các nhà điều hành xóa sẽ không biết nó phải phá hủy một mảng đối tượng vs đối tượng vô hướng trừ khi bạn yêu cầu nó thông qua cấu trúc xóa thích hợp. – Zenilogix