2012-09-14 28 views
16

Tôi đang làm việc với std::shared_ptr và trong quá trình phát triển phần mềm của mình, tôi đã gặp một số trường hợp cho phép tôi nghi ngờ về quản lý bộ nhớ. Tôi đã có một thư viện của bên thứ ba rằng đã cho tôi luôn luôn con trỏ nguyên từ các chức năng và trong mã của tôi, tôi đã chuyển đổi chúng thành std::shared_ptr (từ std và không phải từ tăng. Bằng cách nào sự khác biệt giữa hai là gì?). Vì vậy, chúng ta hãy nói rằng tôi có đoạn mã sau:C + + con trỏ thô và tiêu chuẩn :: shared_ptr

ClassA* raw = new ClassA; 
std::shared_ptr<ClassA> shared(raw); 

gì xảy ra bây giờ khi con trỏ chia sẻ đi ra khỏi phạm vi (giả sử nó đã được công bố tại địa phương trong một chức năng và bây giờ tôi đang thoát khỏi chức năng). Đối tượng ClassA vẫn tồn tại vì một con trỏ thô trỏ đến nó?

Trả lời

27

Không, không. Bằng cách đưa con trỏ đến shared_ptr, bạn đang cho shared_ptr trách nhiệm xóa nó. Nó sẽ làm điều này khi đối tượng shared_ptr cuối cùng đề cập đến nó không còn tồn tại nữa. Con trỏ thô không được tính.

+1

Chỉ cần đưa ra lý do tại sao: shared_ptr không xem con trỏ thô vì không có cách nào shared_ptr có thể biết về nó. Nếu bạn nghĩ về cách bạn sẽ tự mình thực hiện shared_ptr thì bạn sẽ thấy rằng bạn không thể phát hiện nếu có bất kỳ con trỏ thô nào đến dữ liệu. – Wutz

+1

+1. Ngoài ra, đây là lý do tại sao bạn nên 'new' đối tượng trên cùng một dòng khi bạn tạo' shared_ptr'. Thậm chí tốt hơn, sử dụng ['make_shared'] (http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared) –

+0

Cảm ơn, trên thực tế, tôi đồng ý rằng không có cách nào để tìm ra nếu một con trỏ thô là chỉ vào đối tượng. Trong trường hợp này, nó chỉ nguy hiểm cho con trỏ thô vì nó sẽ trỏ đến một đối tượng bị hủy vì shared_ptr sẽ phá hủy nó khi nằm ngoài phạm vi – ISTB

2

Không, đối tượng ClassA sẽ bị hủy. Trừ khi bạn không sao chép shared_ptr một nơi nào đó ngoài phạm vi để bộ đếm tham chiếu của nó là> 1.

5

không. Con trỏ được chia sẻ sẽ xóa nó.

Nếu bạn có thư viện của bên thứ ba cung cấp cho bạn một con trỏ, bạn cần chắc chắn rằng bạn đã xóa nó theo cách chính xác. Nếu lib của bên thứ ba đã cấp phát nó với 'malloc' chẳng hạn, thì bạn cần sử dụng việc triển khai 'miễn phí' mà lib sử dụng. Bạn cần phải chắc chắn nó được phân bổ như thế nào.

Thư viện có cung cấp cách phá hủy các đối tượng cung cấp cho bạn không? Trong trường hợp đó, bạn nên sử dụng chức năng đó để tiêu diệt nó.

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