Giả sử ta có một đối tượng sau:
class Object {
public:
void function(){std::cout << "Function is called" << std::endl;}
};
Con trỏ bình thường:
Object *A = new Object(); // Khởi tạo một đối tượng trong vùng nhớ Heap sử dụng từ khóa new
A -> function(); // Làm một việc gì đó với đối tượng A đã được khởi tạo.
delete A; // Sau khi làm xong, bạn phải giải phóng vùng nhớ đã tạo đi.
Vấn đề rò rỉ bộ nhớ có thể xảy ra nếu:
- Một là bạn quên hủy vùng nhớ sau khi cấp phát (tức là quên câu lệnh
delete A
) - Hai là nhỡ hàm
A -> function()
chạy sai, chương trình bị dừng, mà bị dừng tức là:- Câu lệnh đầu tiên được chạy, vùng nhớ đã được khởi tạo.
- Câu lệnh thứ hai được chạy, bị sai, chương trình bị dừng.
- Câu lệnh thứ ba không được chạy, vùng nhớ cấp phát tại câu lệnh đầu tiên sẽ không được giải phóng.
Con trỏ thông minh:
std::unique_ptr<Object> A(new Object()); // Khởi tạo đối tượng A với con trỏ thông minh,
// lấy ví dụ sử dụng con trỏ thông minh unique_ptr
A -> function(); // Làm một việc gì đó với đối tượng A đã được khởi tạo.
Vấn đề rò rỉ bộ nhớ hiếm khi có thể xảy ra vì:
- Con trỏ thông minh tự động xóa vùng nhớ sau khi bạn cấp phát mà không cần câu lệnh
delete A
- Con trỏ thông minh cũng tự động xóa vùng nhớ mặc dù chương trình có thể chạy sai và bị dừng đột ngột ở câu lệnh thứ 2.
Vậy kết luận, con trỏ thông minh có thể quản lý vùng nhớ một cách tự động thay vì phải tự bạn quản lý nếu sử dụng con trỏ bình thường.
[Cập nhật]
Vẫn có trường hợp rò rỉ bộ nhớ có thể xảy ra mặt dù bạn sử dụng con trỏ thông minh, xem bình luận của @xuans2huy bên dưới.
Về bản chất thì con trỏ thông minh cũng giống như con trỏ bình thường trong C++ thôi, bạn hoàn toàn có thể sử dụng con trỏ thông minh như sử dụng con trỏ bình thường, điểm khác biệt ở đây đó là khi sử dụng con trỏ bình thường bạn phải tự quản lý vùng nhớ của mình, cấp phát, sử dụng và luôn nhớ phải giải phóng vùng nhớ khi không sử dụng nữa, khi sử dụng con trỏ thông minh, bạn không cần quan tâm tới vấn đề này, bởi vì nó có thêm cơ chế tự động quản lý vùng nhớ, khi không còn sử dụng nữa con trỏ thông minh sẽ tự động giải phóng vùng nhớ đã cấp phát.
Một số kiểu con trỏ thông minh mình biết như:
std::unique_ptr
std::shared_ptr
std::weak_ptr
Ngoài ra còn có con trỏ thông minh được hỗ trợ bởi thư viện Boost. Bạn nên nhớ là phiên bản C++ 11 trở lên mới có hỗ trợ con trỏ thông minh nhé.
Còn một con trỏ thông minh khác đó là std::auto_ptr
nhưng bị xem là hoạt động không hiệu quả ở phiên bản C++ 11 và đã bị loại bỏ hoàn toàn ở phiên bản C++ 17, sử dụng các con trỏ thông minh còn lại để thay thế.