Sự khác biệt giữa con trỏ treo lơ lửng và rò rỉ bộ nhớ


79

Tôi không hiểu sự khác biệt giữa con trỏ treo và rò rỉ bộ nhớ. Hai thuật ngữ này liên quan như thế nào?

Câu trả lời:


144

Một con trỏ lơ lửng trỏ đến bộ nhớ đã được giải phóng. Bộ nhớ không còn được phân bổ. Cố gắng truy cập nó có thể gây ra lỗi Phân đoạn.

Cách phổ biến để kết thúc với một con trỏ treo lơ lửng:

Bạn đang trả về một địa chỉ là một biến cục bộ, địa chỉ này sẽ vượt ra khỏi phạm vi bởi điều khiển thời gian được trả lại cho hàm gọi. (Hành vi không xác định)

Một ví dụ về con trỏ treo lơ lửng phổ biến khác là truy cập vào một vị trí bộ nhớ thông qua con trỏ, sau khi phần mềm miễn phí đã được gọi một cách rõ ràng trên bộ nhớ đó.


Một rò rỉ bộ nhớ là bộ nhớ mà chưa được giải thoát, không có cách nào để truy cập (hoặc giải phóng nó) bây giờ, khi không có những cách để có được nó nữa. (Ví dụ: một con trỏ tham chiếu duy nhất đến vị trí bộ nhớ được cấp phát động (và không được giải phóng) hiện trỏ đến một nơi khác.)

Char-ptr ch là một biến cục bộ nằm ngoài phạm vi ở cuối hàm, làm rò rỉ 10 byte được cấp phát động .


Bài viết này cũng có thể hữu ích stackoverflow.com/questions/127386/...
bkausbk

22

Bạn có thể coi đây là những mặt đối lập của nhau.

Khi bạn giải phóng một vùng bộ nhớ, nhưng vẫn giữ một con trỏ đến nó, con trỏ đó đang treo lơ lửng:

Khi bạn làm mất con trỏ, nhưng vẫn giữ bộ nhớ được cấp phát, bạn bị rò rỉ bộ nhớ:


16

Con trỏ treo là một con trỏ có giá trị (không phải NULL) tham chiếu đến một số bộ nhớ không hợp lệ cho loại đối tượng bạn mong đợi. Ví dụ: nếu bạn đặt một con trỏ cho một đối tượng thì ghi đè lên bộ nhớ đó bằng một thứ khác không liên quan hoặc giải phóng bộ nhớ nếu nó được cấp phát động.

Một rò rỉ bộ nhớ là khi bạn tự động phân bổ bộ nhớ từ đống nhưng không bao giờ giải phóng nó, có thể là vì bạn bị mất tất cả các tham chiếu tới nó.

Chúng có liên quan với nhau ở chỗ chúng đều là các tình huống liên quan đến con trỏ được quản lý sai, đặc biệt là liên quan đến bộ nhớ được cấp phát động. Trong một tình huống (con trỏ treo lơ lửng), bạn có thể đã giải phóng bộ nhớ nhưng sau đó cố gắng tham chiếu đến nó; trong trường hợp khác (rò rỉ bộ nhớ), bạn đã quên giải phóng bộ nhớ hoàn toàn!


6

Con trỏ nguy hiểm

Nếu bất kỳ con trỏ nào đang trỏ đến địa chỉ bộ nhớ của bất kỳ biến nào nhưng sau khi một số biến đã bị xóa khỏi vị trí bộ nhớ đó trong khi con trỏ vẫn đang trỏ vị trí bộ nhớ đó. Con trỏ như vậy được gọi là con trỏ treo và vấn đề này được gọi là vấn đề con trỏ treo.

Đầu ra: Giá trị rác

Lưu ý: Trong một số trình biên dịch, bạn có thể nhận được thông báo cảnh báo trả về địa chỉ của biến cục bộ hoặc tạm thời

Giải thích: biến x là biến cục bộ. Phạm vi và thời gian tồn tại của nó nằm trong lời gọi hàm do đó sau khi trả về địa chỉ của x biến x đã trở thành dead và con trỏ vẫn đang trỏ ptr vẫn đang trỏ đến vị trí đó.

Giải pháp của vấn đề này: Làm cho biến x là biến tĩnh. Nói cách khác, chúng ta có thể nói một con trỏ có đối tượng trỏ đã bị xóa được gọi là con trỏ treo.

Bộ nhớ bị rò rỉ

Trong khoa học máy tính, rò rỉ bộ nhớ xảy ra khi một chương trình máy tính quản lý sai phân bổ bộ nhớ. Như đơn giản, chúng tôi đã cấp phát bộ nhớ và không Miễn phí thuật ngữ ngôn ngữ khác nói rằng không phát hành nó gọi là rò rỉ bộ nhớ, nó gây tử vong cho ứng dụng và sự cố bất ngờ.


3

Con trỏ giúp tạo phạm vi do người dùng xác định cho một biến, được gọi là Biến động. Biến động có thể là biến đơn hoặc nhóm biến cùng loại ( array) hoặc nhóm biến khác loại ( struct). Phạm vi biến cục bộ mặc định bắt đầu khi điều khiển đi vào một chức năng và kết thúc khi điều khiển ra khỏi chức năng đó. Phạm vi có thể thay thế toàn cầu mặc định bắt đầu khi thực thi chương trình và kết thúc khi chương trình kết thúc.

Nhưng phạm vi của một biến động do một con trỏ nắm giữ có thể bắt đầu và kết thúc tại bất kỳ thời điểm nào trong quá trình thực thi chương trình, điều này phải do lập trình viên quyết định. Nguy hiểm và rò rỉ bộ nhớ chỉ xuất hiện nếu một lập trình viên không xử lý hết phạm vi.

Rò rỉ bộ nhớ sẽ xảy ra nếu một lập trình viên không viết mã ( freecủa con trỏ) cho cuối phạm vi cho các biến động. Bất kỳ cách nào sau khi chương trình thoát khỏi bộ nhớ quy trình hoàn chỉnh sẽ được giải phóng, tại thời điểm đó bộ nhớ bị rò rỉ này cũng sẽ được giải phóng. Nhưng nó sẽ gây ra một vấn đề rất nghiêm trọng cho một quy trình đang chạy trong thời gian dài.

Khi phạm vi của biến động kết thúc (giải phóng), NULLnên được gán cho biến con trỏ. Nếu không, nếu mã truy cập sai, hành vi không xác định sẽ xảy ra. Vì vậy, con trỏ treo lơ lửng không là gì khác ngoài một con trỏ trỏ đến một biến động có phạm vi đã hoàn thành.


3

Rò rỉ bộ nhớ : Khi có một vùng bộ nhớ trong một heap nhưng không có biến nào trong ngăn xếp trỏ đến vùng nhớ đó.

Con trỏ nguy hiểm : Khi một biến con trỏ trong ngăn xếp nhưng không có bộ nhớ trong heap.

Một con trỏ treo lơ lửng cố gắng truy cập mà không phân bổ không gian sẽ dẫn đến lỗi phân đoạn.


3
ví dụ của bạn cho con trỏ treo không thực sự là một con trỏ treo mà là một con trỏ NULL. Ví dụ chính xác sẽ là gán động bộ nhớ cho con trỏ, giả sử bằng cách sử dụng malloc (), và sau đó giải phóng () bộ nhớ đó, điều này làm cho nó trở thành một con trỏ treo. LƯU Ý: sau khi giải phóng, chúng tôi chưa gán nó cho NULL do đó con trỏ vẫn trỏ đến cùng một địa chỉ bộ nhớ khiến nó trở thành một con trỏ treo. Bây giờ, nếu bạn cố gắng truy cập bộ nhớ đó bằng cùng một con trỏ (tức là bỏ tham chiếu con trỏ), bạn có thể gặp lỗi phân đoạn.
sactiw

0

Một con trỏ trỏ đến một vị trí bộ nhớ đã bị xóa (hoặc giải phóng) được gọi là con trỏ treo.

để biết thêm thông tin bấm vào ĐÂY


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.