Một con trỏ khi xin cấp phát thì cần phải giải phóng vùng nhớ của nó sau khi không còn sử dụng.
Mn cho em hỏi, vậy 1 con trỏ 1 struct chứa trong nó 1 thành phần là con trỏ, thì khi delete struct, con trỏ trong struct đó có được tự động giải phóng không? hay nó đi về đâu? hay mình phải tự giải phóng nó trc khi delete struct
Giải phóng thành phần con trỏ trong struct
Không. Tự mình phải giải phóng.
Câu trả lời là cần nha bạn.
Nhưng thấy tag là C++ nên mình có bổ sung thêm một tí là bây giờ code C++ gần như không còn ai xài tới con trỏ “thô” (raw pointer) nữa. Mà thay vào đó sẽ sử dụng smart pointer (std::unique_ptr và std::shared_ptr và các implement tương tự) để tự động hóa việc thu hồi bộ nhớ và mình sẽ không cần gọi new
hay delete
nữa.
OMG, lần đầu tiên e nghe về con trỏ thông minh đó, nhưng có lẽ cần phải nắm tốt đc con trỏ thô trước đã. Nói tóm lại là, miễn là khi cấp phát 1 con trỏ, bất kể khi nào nó hết giá trị sử dụng, thì đều phải giải phóng nó, trong trường hợp của struct chứa con trỏ, em sẽ phải giải phóng nó trước khi giải phóng biến struct chứa nó?
Đúng rồi nhé…
viết code giải phóng nó ở trong destructor của struct đó chứ ko phải trong code sử dụng struct đó nha em :V Viết code cấp phát cho con trỏ ở constructor thì viết code giải phóng cho nó ở destructor, có vậy thôi, ko cần phải delete foo.bar;
trước khi giải phóng foo
:V
à, thêm nữa, giả sử e có 1 con trỏ mảng
int* arr = new int[4] {0} ;
nếu e giải phóng mảng trên bằng delete arr
thay vì delete[] arr
thì sẽ bị sai như nào ạ? Có phải là chỉ phần tử đầu được giải phóng, còn những phần tử sau đó sẽ vẫn còn ở đó và không được giải phóng?
em muốn kiểm chứng thì tạo 1 kiểu Foo
nào đó, viết dtor cho nó ~Foo() { cout << "Foo destroyed\n"; }
là biết bao nhiêu phần tử được free
Làm sao thằng delete[] hoặc free nó biết kích thước dữ liệu con trỏ đang trỏ tới nhỉ
mỗi trình dịch mỗi khác nhưng có thể là với new T[n]
nó thêm 4/8 bytes vào phía trước block được cấp phát, hay cấp phát block có size là n*sizeof(T) + 8
tại 0x########
, rồi ghi n
vào 8 bytes trước đó, và trả về con trỏ tới block đó + 8 bytes: 0xYYYYYYYY = 0xXXXXXXXX + 0x8
:V Khi delete[] 0xYYYYYYYY
nó lấy n
bằng cách lấy 0xYYYYYYYY - 0x8
để ra 0xXXXXXXXX
, gọi n
dtor của n
phần tử T
ở 0xYYYYYYYY
rồi giải phóng block 0xXXXXXXXX
đó :V new
và delete
thì hoạt động như malloc/free nhưng khi delete có gọi thêm 1 dtor. Bởi vậy gọi delete 0xYYYYYYYY
ko những nó ko trừ 8 để lấy n
mà nó chỉ gọi dtor của 1 phần tử ở 0xYYYYYYYY
, lại còn free block 0xYYYYYYYY
là sai block nữa :V