2010-12-15 39 views

Trả lời

16

Nếu ngoại lệ được tăng lên giữa phân bổ và deallocation, rò rỉ bộ nhớ sẽ xảy ra.

void f1() { 
    int* ptr = new int; 

    // do something which may throw an exception 

    // we never get here if an exception is thrown 
    delete ptr; 
} 

Mỗi lần f1 chấm dứt với một ngoại lệ, 4 byte đang bị rò rỉ (giả sử int là 4 byte).

+0

Điểm tuyệt vời nhờ watson – ashmish2

+3

... một trong những lý do mà con trỏ thông minh "thông minh hơn" con trỏ thô như 'int *' (không có hàm hủy): http://stackoverflow.com/questions/106508/what-is -a-smart-pointer-và-when-should-i-use-one – HostileFork

13

Một rò rỉ bộ nhớ là do khi bạn phân bổ bộ nhớ, có không chưa deallocated nó, và bạn sẽ không bao giờ có thể deallocate nó bởi vì bạn không thể truy cập nó nữa.

Ví dụ, đoạn mã sau gây ra rò rỉ bộ nhớ kích thước sizeof(int):

int * a = malloc(sizeof(int)); //allocate memory 
a = 0; //this will cause a memory leak 

Điều này tạo ra một sự rò rỉ bộ nhớ, bởi vì bây giờ chúng tôi sẽ không bao giờ có thể deallocate bộ nhớ phân bổ cho a.

2

Một new mà không có một delete, một new[] mà không có một delete[], một malloc mà không có một free.

Nghiêm túc, bạn muốn nghe điều gì khác?

6

Bạn cũng có thể bị rò rỉ bộ nhớ khi bạn không giải quyết một số tài nguyên khác như không gọi fclose trên FILE * hoặc một số thư viện khác bởi vì chúng có thể cấp phát bộ đệm không thể truy cập trực tiếp vào chương trình của bạn.

2

Không có lý do nào khác cho rò rỉ bộ nhớ ngoài lý do bạn đề cập đến

+0

Một counterexample cho điều này là câu trả lời của watson1180. – Cam

+0

@Cam: Tôi không nghĩ vậy, trong ví dụ của watson1180, anh ấy đã quên gọi 'delete' (mặc dù nó được viết trong mã). –

+0

@Matthieu: Hmm ... thực sự. Đáng buồn là tôi hiện không thể bỏ câu trả lời của beb0. – Cam

4

Giả sử bạn đã tạo một lớp kế thừa một số lớp khác không có trình phá hủy ảo. Nếu loại con trỏ tới lớp này không phải là lớp dẫn xuất nhất (điều này thường xảy ra nếu bạn sử dụng một nhà máy trừu tượng) thì chỉ có destructor từ kiểu con trỏ sẽ được gọi và bất cứ thứ gì bạn đã hy vọng làm miễn phí class destructor sẽ bị rò rỉ.

Đây là lỗi rất phổ biến và một số lần khó xem.

Dù sao, nếu bạn muốn tránh rò rỉ bộ nhớ với C++ làm theo quy tắc này:

  • thích đi tham khảo chứ không phải là con trỏ
  • Sử dụng con trỏ thông minh bất cứ khi nào có thể (xem: shared_ptr)
+0

Tất nhiên, tiêu chuẩn nói rằng hành vi không xác định của nó nếu destructor của lớp cơ sở không phải là ảo, vì vậy bạn đang giả mạo với cái ác và rò rỉ bộ nhớ ít nhất là lo lắng của bạn ở đây. Đối với 'shared_ptr', nó đôi khi hữu ích, nhưng có nhiều con trỏ/container thông minh tốt hơn nhiều để sử dụng hàng ngày. Nó chắc chắn phải là sự lựa chọn cuối cùng. –

0

Tôi ngạc nhiên không ai nhắc đến tham nhũng bộ nhớ.

Tôi nhớ một trường hợp khi chúng tôi có một khối cố định kích thước cố định thô được thực hiện dưới dạng danh sách được liên kết.

Một số người đã làm sai lệch kích thước tính toán, dẫn đến sao chép dữ liệu chỉ là một vài byte vượt quá kích thước khối tối đa (con trỏ chỉ dài 2 byte tại thời điểm :)). Sau đó nó sẽ ghi đè liên kết "tiếp theo" nằm ở đầu của khối miễn phí tiếp theo với rác đã xảy ra để được lấp đầy bằng số không.

Điều này có hậu quả của việc cắt đứt chuỗi khối miễn phí. Kể từ thời điểm đó, các phần mềm khác vẫn duy trì các con trỏ của riêng chúng cho bất kỳ khối nào mà chúng đang sử dụng, các progam dường như chạy tốt.

Nhưng tất nhiên danh sách đã bị thiếu một vài khối một lần trong một thời gian, và rò rỉ này cuối cùng đã cạn kiệt các khối miễn phí, bỏ đói ứng dụng cho đến chết.

0

Ví dụ sau, được viết bằng mã giả, nhằm mục đích cho biết cách rò rỉ bộ nhớ có thể xảy ra và các hiệu ứng của nó mà không cần bất kỳ kiến ​​thức lập trình nào. Chương trình trong trường hợp này là một phần của một số phần mềm rất đơn giản được thiết kế để điều khiển thang máy. Phần này của chương trình được chạy bất cứ khi nào bất cứ ai bên trong thang máy nhấn nút cho một tầng.

Khi một nút được nhấn:

Get some memory, which will be used to remember the floor number 
    Put the floor number into the memory 
    Are we already on the target floor? 
    If so, we have nothing to do: finished 
    Otherwise: 
     Wait until the lift is idle 
     Go to the required floor 
     Release the memory we used to remember the floor number 

Vụ rò rỉ bộ nhớ sẽ xảy ra nếu số sàn yêu cầu là cùng một tầng mà thang máy là trên; điều kiện để giải phóng bộ nhớ sẽ bị bỏ qua. Mỗi lần trường hợp này xảy ra, nhiều bộ nhớ bị rò rỉ.