Phát triển bao nhiêu năm rồi mà còn bug là sao?

Sau không biết bao nhiêu năm phát triển thì các lỗi Segmentation Fault, Memory Lead, Crash vẫn tồn tại. Các lỗi này có đặc điểm là ở dạng tiềm ẩn, code chạy phà phà vậy đó, tuy nhiên khi rơi vào các corner case thì mới xuất hiện, và khi xuất hiện thì cũng không dễ gì mà debug và fix nó.

Bao nhiêu năm code thì mình thấy các lỗi này tồn tại ở tất cả các công ty, tất cả các dự án sử dụng C/C++, đến đây nhiều bạn sẽ bảo – Láo, ta đây code chưa bao bị mem lead, hay crash gì đâu. Tuy nhiên hãy đọc các lý do sau để xem có thuyết phục không nhé. 

Vấn đề là do đâu, do ngôn ngữ hay do con người ?

– Ở góc nhìn của anh Dev cứng, ít để xảy ra lỗi thì ảnh bảo: Có gì khó đâu, code lâu thì có kinh nghiệm và biết cách làm thôi.

– Ở góc nhìn của anh code gà (như mình ) : á , tưởng khai báo vậy sài rồi thôi chớ. Thôi để rút kinh nghiệm, và sau mấy chục lần như vậy thì anh code mềm trở thành anh code cứng.

– anh ngôn ngữ ảnh bảo : tao đã đưa ra các thông tin rõ ràng rồi, ai biểu tụi mình không chịu đọc kỹ rồi cứ code tào lao, có lỗi thì cứ đổ thừa. 

– Ở cấp độ anh CEO thì ảnh bảo như vậy là không ổn chút nào, mô hình như vậy phụ thuộc cảm xúc và trình độ kỹ sư quá nhiều, cần có một giải pháp ít phụ thuộc vào con người hơn !

Shared Pointer ra đời thế nào ?

– Khi làm việc với C/C++ thì khó trảnh khỏi trường hợp có nhiều API, nhiều module cùng thao tác đọc, khi, cấp phát bộ nhớ cho một con trỏ. Các biến con trỏ khác thì củng có thể tham chiếu đến con trỏ này. Vậy ai là người cuối cùng sử dụng nó, ai là người sẽ free nó  ? Chưa kể khi sài các linked list, mà trong linked list này có phần tử sử dụng Heap Memory thì nếu không phải người tạo ra nó free thì củng không ai biết mà free.

– Để giải quyết vần đề này thì từ Smart Pointer ra đời. Ý tưởng của nó là khi bạn tạo một con trỏ thông minh thì hệ thống sẽ khởi tạo một vùng nhớ và được quản lý bởi hệ thống sau đó cung cấp địa chỉ này cho người dùng. Mỗi khi có một phép gán đến vùng nhớ này thì hệ thống sẽ tăng số lượt tham chiếu lên. Và khi không còn ai tham chiếu đến vùng nhớ này nữa thì hệ thống sẽ free vùng nhớ luôn.

– Nhìn đơn giản vậy thôi nhưng lại vô cùng hiệu quả, chúng ta không còn lo lắng ai sẽ free bộ nhớ sau lần sử dụng cuối cùng ( để tránh rò rì vùng nhớ – vùng nhớ không còn sử dụng nữa nhưng không được free làm cho hệ thống không thể tái sử dụng được ).

Cách sử dụng shared pointer

– Thư viện cần phải include 

#include <memory>
– Khởi tạo con trỏ p1 là con trỏ chia sẽ
shared_ptr<int> p1 = make_shared<int>();
– Kiểm tra số lượng tham chiếu của con vùng nhớ quản lý bởi hệ điều hành.
cout << "Reference count of managed pointer : " << p1.use_count() << "\n";
– Khởi tạo con trỏ chia sẽ p2 tham chiếu đến con trở p1
shared_ptr<int> p2(p1);
– Kiểm tra số lượng tham chiếu của vùng nhớ quản lý bởi hệ điều hành sẽ là 2.
cout << "Reference count of p1 : " << p1.use_count() << "\n";

cout << "Reference count of p2 : " << p2.use_count() << "\n";
– Không muốn tham chiếu đến vùng nhớ quản lý nữa.
p1.reset(); hoặc p1 = nullptr;