30/09/2018, 20:16

Toán tử delete không thể thu hồi các ô nhớ của mảng động

Mình đang gặp một vấn đề như sau:
Mình tạo một mảng động gồm n phần tử và gán giá trị cho các phần tử này
sau đó mình sử dụng toán tử delete để thu hồi toàn bộ vùng nhớ đã cấp phát
theo lỳ thuyết thì giá trị của các con trỏ trong mảng sẽ là không xác định
nhưng khi mình code ra thì các giá trị này không hề thay đổi
nghĩa là toán tử delete thực hiện vô ích, không có tác dụng gì cả.

 #include < iostream.h >
     int main() {
         int * p, n;
         cin >> n;
         p = new int[n];
         for (int i = 0; i < n; i++)
             p[i] = i;
         for (int i = 0; i < n; i++)
             cout << p[i] << " ";
         cout << '
';
         delete[] p;

         for (int i = 0; i < n; i++)
             cout << p[i] << " ";
     }

mình gõ vào số 5 và nó hiển thị ra như sau:

5
0 1 2 3 4
0 1 2 3 4

nhờ mọi người tìm lỗi sai giúp mình

Mu Hoasua viết 22:18 ngày 30/09/2018

bạn xem lại có phải sau khi delete thì phải gán con trỏ băng null không nếu minh không nhớ nhầm

Dép Lào viết 22:28 ngày 30/09/2018

Bạn khai báo là int *p mà tại sao lại là delete[] p; thử bỏ [] đi

Nguyễn Thành Trung viết 22:19 ngày 30/09/2018

mình nghĩ gán null vào không để làm gì cả vì mình không quan tâm con trỏ nó trỏ đến đâu mà quan tâm đến việc đã thu hồi được toàn bộ các ô nhớ được cấp phát hay chưa.

Nguyễn Thành Trung viết 22:21 ngày 30/09/2018

mình đang tạo mảng động mà phải có n phần tử và delete nó phải có [] chứ

bài này mình làm theo bài của ad

Gió viết 22:24 ngày 30/09/2018

delete không có nghĩa là thay đổi các giá trị đã nhập.
Để dễ hình dung, ta so sánh việc cấp phát động như việc thuê ô tô chở hàng, việc cấp phát <=> thuê, bạn gán giá trị <=> chất hàng lên, delete <=> trả lại xe. Người cho mượn xe này rất lười chẳng bao giờ kiểm tra xem lúc nó giao xe, hay trả xe ở trong xe có gì. Việc thay đổi chỉ xảy ra khi, xe đã cho mượn và chất thứ khác lên.
Th của bạn có lẽ chưa có lẽ chưa ai sử dụng. Trong th này bạn không thuê mà sử dụng thì rất dễ bị bắt (“bug”). Hành vi này gọi là undefined behavior

Nguyễn Thành Trung viết 22:26 ngày 30/09/2018

không hiểu câu cuối của bạn. Ở phía dưới là kết quả của việc mình trả xe rồi nhưng mà … vẫn có thể sử dụng nó?

  include < iostream.h >
     int main() {
         int * p, n;
         cin >> n;
         p = new int[n];
         for (int i = 0; i < n; i++)
             p[i] = i;
         for (int i = 0; i < n; i++)
             cout << p[i] << " ";
         cout << '\n';
         delete[] p;

         for (int i = 0; i < n; i++)
             cout << p[i] << " ";
     }

hiển thị màn hình:

5
0 1 2 3 4
0 1 4 9 16

Nguyễn Thành Trung viết 22:16 ngày 30/09/2018

Có cách nào để biết được liệu các ô nhớ đã được giải phóng hay chưa?
Mình dùng C-free
IDE này không biết có phím tắt có thể giúp mình kiểm chứng được điều trên?

viết 22:27 ngày 30/09/2018

giải phóng thì chỉ đơn giản là đánh dấu vùng nhớ đó ko có ai sử dụng nữa. Nếu phải chép đè dữ liệu rác lên vùng nhớ đó nữa thì sẽ rất chậm. Vd 1 vùng nhớ 100MB, giải phóng vùng nhớ này thì chỉ cần đánh dấu 100MB này ko có ai sử dụng nữa là xong. Nếu phải chép thêm dữ liệu rác vào 100MB này thì cực kì chậm.

để biết được các ô nhớ đã đc giải phóng hay chưa thì nhìn code xem có delete hay chưa ~.~ Nếu ngại nhìn thì sau khi delete gán NULL cho con trỏ đó là được:

delete [] p;
p = NULL; //ko cần thiết nhưng nếu cần thận thì thêm vào để tránh xài tiếp vùng nhớ đã được giải phóng mà p vẫn còn trỏ tới.

đương nhiên là vẫn sử dụng vùng nhớ sau khi giải phóng được. Vd bạn thuê 1 căn nhà để buôn bán, hết tháng trả lại nhà, nhưng sau khi trả thì nhà đó ko ai thuê nữa, bạn biết địa chỉ nhà đó, vẫn tiếp tục sử dụng nhà đó để buôn bán. Chả sao cả. Chỉ khi nào có người khác đòi thuê căn nhà đó và chủ nhà phát hiện ra thì bạn tiêu tùng.
căn nhà = vùng nhớ, bạn = con trỏ, new = thuê nhà, delete = trả nhà, người khác = con trỏ khác. Chủ nhà = hệ điều hành (chịu trách nhiệm cấp phát bộ nhớ)

Nguyễn Thành Trung viết 22:19 ngày 30/09/2018

ban đầu mình nghĩ là delete sẽ làm cho mọi thứ trở về ban đầu, nghĩa là không thể sử dụng các ô nhớ nữa
sau khi delete mà vẫn dùng được thì mình nghĩ chắc sai ở đâu
chính vì mình nghi ngờ cái câu lệnh delete nên mới tìm cách khác để kiểm tra
chắc phải chờ cho máy nó bốc khói để biết tài nguyên có bị lãng phí hay không

Bài liên quan
0