2012-06-19 42 views
5

Các lỗi có thể xảy ra khi cấp phát bộ nhớ bằng cách sử dụng malloc ngoại trừ out of memory là gì? Các chiến lược tốt nhất để xử lý các lỗi đó là gì?xử lý lỗi malloc

Đối với một số out of memory exception là cần thiết để giải phóng con trỏ ngay cả khi phân bổ bộ nhớ không thành công?

+2

Cuộc sống thực còn tồi tệ hơn: Trên Linux chuẩn, cuộc gọi 'malloc' của bạn có thể thành công, nhưng bộ nhớ không thực sự khả dụng và quá trình của bạn bị giết. Hệ điều hành * oversubscribes * bộ nhớ theo mặc định. Nó thường không phải là một vấn đề lớn. –

+1

Rất may mặc định này là dễ dàng cố định bởi bất cứ ai muốn hệ thống Linux của họ cư xử tốt hơn Win95 ... ('echo" 2 ">/proc/sys/vm/overcommit_memory') –

Trả lời

11

Trong C không có ngoại lệ (không phải bạn cũng có thể sử dụng ngôn ngữ), vì vậy cách duy nhất malloc có thể báo hiệu lỗi không trả về con trỏ rỗng. Vì vậy, bạn phải kiểm tra giá trị trả lại. Nếu nó là 0, phân bổ thất bại (vì lý do gì) và không có bộ nhớ được cấp phát - không có gì để giải phóng; nếu không phân bổ cho số tiền yêu cầu (*) đã thành công và bạn sẽ phải giải phóng bộ nhớ khi không còn cần thiết nữa.

(*) hãy cẩn thận với các luồng thừa: malloc có tham số size_t, rất có thể là số chưa được ký. Nếu bạn yêu cầu size * sizeof(int) byte có dấu chưa ký size và các luồng tràn nhân (có thể là lỗi khi nhận giá trị size), kết quả là một số nhỏ. malloc() sẽ phân bổ số lượng nhỏ của byte cho bạn trở về với không null và bạn chỉ số vào mảng được trả dựa trên giá trị thực tế (lớn) của size, có thể dẫn đến Phân khúc lỗi hoặc tương đương của nó

+1

bạn có thể cụ thể hơn về tràn –

+0

@AmanDeepGautam - xem cập nhật – Attila

+0

cảm ơn !.Tôi đã nhận được nó –

0

Hết bộ nhớ là lỗi duy nhất có thể phát hiện được ... các lỗi khác như giải phóng bộ nhớ đã được giải phóng có thể dẫn đến sự cố.

Một chiến lược để kiểm tra bộ nhớ trong C là sử dụng trình bao bọc cho malloc và realloc (bạn có thể gọi chúng là xmalloc và xrealloc) để kiểm tra bộ nhớ và nếu có hành động lỗi ... in thư và thoát, hoặc có thể cố gắng giải phóng các vùng nhớ và sau đó thử lại việc cấp phát. Điều này đặt tất cả các thử nghiệm ở một nơi, tạo ra các thông báo lỗi nhất quán, và đảm bảo rằng tất cả các nỗ lực phân bổ được kiểm tra thất bại. Các nhược điểm có thể xảy ra được thảo luận trong phần bình luận bên dưới.

Trước đây, chiến lược này hiếm khi có mã C (phù hợp với chất lượng thấp chung trong mã viết bằng ngôn ngữ cổ này), nhưng ngày nay một số khung thư viện trưởng thành kết hợp loại điều này (mặc dù việc triển khai để lại cái gì đó để mong muốn; một lần nữa, xem bình luận bên dưới). Một cách tiếp cận khác, điều rất được khuyến khích, là từ bỏ C và chuyển sang một ngôn ngữ hiện đại hơn ... có thể là C++, trong đó bất kỳ sự thất bại nào của new dẫn đến ngoại lệ bad_alloc.

Đối với câu hỏi của bạn ... nếu malloc không thành công, nó trả về NULL; không có con trỏ nào miễn phí. (miễn phí (NULL) là một no-op). Nếu realloc không thành công thì phân bổ ban đầu vẫn không thay đổi. Bạn có thể tìm thấy những điều này bằng cách đọc các trang hoặc thông số kỹ thuật như http://pubs.opengroup.org/onlinepubs/7908799/xsh/realloc.html

+1

-1 cho 'malloc' là một * thực hành lập trình cực kỳ có hại * nhưng phổ biến cần được bãi bỏ. Không có xung quanh nó - bạn phải xử lý thất bại của 'malloc', và không có cách nào" dễ dàng hơn "để xử lý nó có thể đạt được với một wrapper. Các trình bao bọc mà chỉ hủy bỏ chương trình làm cho nó dễ dàng viết * mã bị hỏng * mà không kiểm tra lỗi 'malloc' (vì nó có thể giả định trình bao bọc của bạn không bao giờ trả về thất bại) và nó gần như không thể sửa có thể sử dụng được trong phần mềm mạnh mẽ. Các thư viện chính như GMP và glib bị vấn đề này. –

+0

Đó là thối hoàn toàn. –

+0

Bạn có muốn giải thích không? –

1

Tôi nhận ra điều này giống như phích cắm sản phẩm, nhưng bạn có thể đọc về các loại lỗi phân bổ bộ nhớ khác nhau trong phần ghi của chúng tôi trên CheckPointer. lỗi quản lý bộ nhớ, bao gồm các lỗi phân bổ như vậy.