2010-07-02 11 views
11

Tôi đã được hỏi điều này trong một cuộc phỏng vấn gần đây, về cơ bản viết một hàm để kết hợp các chức năng miễn phí và gán null. Tôi trả lời theo cách sau đây:Viết hàm để giải phóng con trỏ và gán nó NULL

void main() 
{ 
     int *ptr; 
     ptr = new int; 
     ptr = newdelete(ptr); 
} 

(int*) newdelete (int *ptr) 
{ 
     delete(ptr); 
     return NULL; 
} 

Vì vậy, sau khi thực hiện, các địa phương để ptrmain sẽ giữ giá trị null như tôi đang trở về nó từ newdelete chức năng. Nếu tôi vừa chỉ định NULL trong hàm newdelete, thì ptr địa phương thành newdelete sẽ bị hủy và không phải là ptr địa phương thành main.

Tôi nghĩ giải pháp của tôi là chính xác, người phỏng vấn cũng chấp nhận nó. Tuy nhiên, anh đang chờ đợi một số câu trả lời khác. Ông đã nhấn mạnh tôi không trả lại NULL từ chức năng và vẫn đạt được kết quả mong muốn.

Có cách nào để thực hiện điều đó không? Tất cả những gì tôi có thể nghĩ đến là vượt qua một đối số khác là con trỏ đến con trỏ ptr địa phương đến main, nhưng tôi không thấy lý do tại sao nó tốt hơn so với những gì tôi đã làm!

+0

Tôi đoán bạn có nghĩa là 'new int' vì' New' không phải là toán tử 'C++' được định nghĩa. – ereOn

+1

Chuyển một tham chiếu đến con trỏ. –

+0

http://stackoverflow.com/questions/1265666/reason-why-not-to-have-a-delete-macro-for-c/1265681#1265681 – Goz

Trả lời

36

Có cách nào để thực hiện điều đó không ??

template <typename T> void safeDelete(T*& p){ 
    delete p; 
    p = 0; 
} 

int main(int argc, char** arv){ 
    int * i = new int; 
    safeDelete(i); 
    return 0; 
} 
+0

+1, giải pháp linh hoạt và thẳng thắn nhất. – stinky472

+4

Vì chỉ có mã, lý do tại sao đây là giải pháp tốt hơn là bạn đảm bảo rằng con trỏ sẽ bị vô hiệu hóa trong suốt cuộc gọi. Với mã trong câu hỏi bạn có thể bỏ qua (quên) giá trị trả về: '/ * p = */newdelete (p);' và bộ nhớ sẽ được giải phóng nhưng con trỏ sẽ không rỗng. –

+6

Hãy nhớ rằng bạn sẽ cần một phiên bản thứ hai của điều này cho mảng. –

8

Tôi đoán ông đang mong đợi một cái gì đó như:

void reset(int*& ptr) 
{ 
     delete(ptr); 
     ptr = NULL; 
} 

Một giải pháp thậm chí sạch sẽ đã được sử dụng một boost::shared_ptr<> và chỉ đơn giản là gọi ptr.reset(). Tuy nhiên, tôi cho rằng đây không phải là một lựa chọn.

+1

Điều gì sẽ xảy ra nếu họ không muốn các ngữ nghĩa con trỏ được chia sẻ? Không có điểm có thêm chi phí nếu bạn không cần nó. –

+1

@Peter scoped_ptr trong trường hợp đó tương tự như vậy cung cấp thiết lập lại. – stinky472

+0

@Peter: Tôi nên đề cập đến 'scoped_ptr' thay vì' shared_ptr' (tôi sử dụng sau này thường xuyên hơn để nó đến đầu tiên của tôi). Cho dù nó được chia sẻ hay scoped, sử dụng một con trỏ thông minh là an toàn hơn bất kỳ 'safeDelete()' chức năng kết hợp với con trỏ thô. – ereOn

1

Nếu requrement đã không viết một hàm, bạn luôn có thể viết một macro mà sẽ làm điều đó cho bạn cũng như:

#define my_delete(x) { delete x; x = NULL; } 

Tất nhiên, gọi nó như thế này sẽ giúp bạn có được vào tất cả các loại của sự cố:

my_delete(ptr++) 

Vì vậy, tôi nghĩ tôi thích cách không vĩ mô hơn.

1

Bạn không

Bạn sử dụng con trỏ thông minh như auto_ptr, shared_ptr rằng null riêng của mình.