Giải phóng thành phần con trỏ trong struct

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

1 Like

Không. Tự mình phải giải phóng.

4 Likes

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.

5 Likes

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é…

3 Likes

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

4 Likes

à, 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?

2 Likes

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

4 Likes

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ỉ :relieved:

2 Likes

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ử T0xYYYYYYYY rồi giải phóng block 0xXXXXXXXX đó :V newdelete 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

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?