2011-11-17 51 views
5

Dưới đây là những gì tôi đã sao chép từ MSDN về new điều hành:Xóa một mảng các con trỏ đến các hàm?

Nhà điều hành new không thể được sử dụng để phân bổ một chức năng, nhưng nó có thể được sử dụng để phân bổ con trỏ đến chức năng. Ví dụ sau đây phân bổ và sau đó giải phóng một mảng bảy con trỏ đến các hàm số trả về số nguyên.

int (**p)() = new (int (*[7])()); 
delete *p; 

Vâng không có gì lạ với dòng đầu tiên là, nó phân bổ một mảng của con trỏ đến chức năng, nhưng tôi chỉ không hiểu tại sao thứ hai xóa mảng đó? Tôi nghĩ rằng nó phải là:

delete[] *p; 

Bất cứ ai có thể giải thích điều này?

+0

có,,,,, –

+6

Không, nó phải là 'xóa [] p' (không có dấu hoa thị). – avakar

+0

và cách "xóa * p;" hợp lệ? đó là những gì tôi không thể tìm ra – codekiddy

Trả lời

5

Thẳng thắn mà nói câu trả lời đúng được viết trong số của avakar nhận xét. Mã đúng là

delete[] p; 

delete *p; là không chính xác vì hai lý do:

  1. chúng ta phải sử dụng delete[] cho tất cả các mảng cấp phát động. Sử dụng delete sẽ gây ra hành vi không xác định.
  2. con trỏ đến chức năng tĩnh và là thành viên không thể bị xóa
+0

Tôi nghĩ điểm thứ hai của bạn được diễn đạt một cách không may, mặc dù bạn đúng rằng' xóa * p' là sai trên hai tài khoản. Các con trỏ tới chắc chắn có thể bị xóa, cho dù chúng được phân bổ. Một con trỏ, sau khi tất cả, chỉ cần rằng, một con trỏ. Tuy nhiên 'delete * p' không xóa con trỏ, nhưng cố gắng xóa hàm chỉ định. – Damon

+0

Mặc dù thừa nhận rằng từ ngữ của tôi không tốt hơn nhiều ... vì dĩ nhiên không phải con trỏ bị xóa, nhưng điều gì cũng được chỉ ra. Vì vậy, có lẽ "xóa mất một con trỏ và * p không phải là một con trỏ" là từ ngữ phải chính xác. – Damon

+0

Cảm ơn bạn đã trả lời Dmitry, cũng cảm ơn người khác vì đã trả lời! – codekiddy

2

Nếu chúng ta thêm một typedef,

typedef int (*FPtr)(); 

tuyên bố new có thể được viết lại như

FPtr *p = new FPtr[7]; 

vì vậy đây là rõ ràng rằng tài nguyên phải được phát hành với

delete[] p; 

như được giải thích bởi những người khác.


BTW, trang MSDN cho VS 2008 trở lên sử dụng mã đúng.

int (**p)() = new (int (*[7])()); 
delete [] p; 
+0

Điều này có thể là do tôi đã thêm liên kết bằng cách googling và do đó có thể đã liên kết một phiên bản khác với phiên bản OP được trích dẫn. Lỗi của tôi. –

+0

Tôi đã sao chép mã từ phiên bản visual studio 2008: D – codekiddy

+0

@codekiddy: Nó nói 'xóa [] 'trong [phiên bản 2008 của Hoa Kỳ] (http://msdn.microsoft.com/en-uS/library/kewsb8ba % 28v = VS.90% 29.aspx). – kennytm

Các vấn đề liên quan