2
Con trỏ thông minh trong C++ là gì?
0
Yomoto0 đã đăng:

Con trỏ thông minh trong C++ có khác gì so với con trỏ bình thường không? Tại sao nó được gọi là Smart Pointer hay con trỏ thông minh? Ai giải thích giùm mình với.

thêm bình luận...
3
Minh Tâm50 đã đăng:

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.

đã bổ sung 5.7 năm trước bởi
Avatar: Minh Tâm Minh Tâm50

@MinhTâm, vấn đề rò rỉ bộ nhớ vẫn có cơ hội xảy ra nếu bạn lập trình không cẩn thận tạo nên một tham chiếu vòng tròn, tức là đối tượng a -> b -> a hoặc a -> a,..., bởi vì các con trỏ thông minh hoạt động dựa trên số lượng tham chiếu của một đối tượng mà quyết định xem đối tượng đó có được giải phóng vùng nhớ hay không, số lượng tham chiếu của đối tượng bằng 0 thì lập tức giải phóng vùng nhớ, trong trường hợp tham chiếu vòng tròn, số lượng tham chiếu của đối tượng không bao giờ giảm bằng 0, do đó con trỏ thông minh quyết định không giải phóng vùng nhớ đó, kết quả là rò rỉ bộ nhớ.

xuans2huy 12.08.2018

Cảm ơn @xuans2huy, mình đã cập nhật câu trả lời.

Minh Tâm 12.08.2018
thêm bình luận...
1
minhkiet150 đã đăng:

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ế.

đã bổ sung 6.3 năm trước bởi
Zootopia60
Không lòng vòng anh như Hải Phòng
thêm bình luận...
Bạn đang thắc mắc? Ghi câu hỏi của bạn và đăng ở chế độ cộng đồng (?)