2010-03-20 33 views
26

Tôi có một lỗi khá nghiêm trọng trong chương trình của tôi - thỉnh thoảng gọi đến new() ném bad_alloc.Gỡ rối chiến lược để tìm nguyên nhân của bad_alloc

Từ các tài liệu tôi có thể tìm thấy trên bad_alloc, nó dường như bị ném vì những lý do:

  1. Khi máy tính chạy ra khỏi bộ nhớ (mà chắc chắn không xảy ra, tôi có 4GB RAM, chương trình ném bad_alloc khi sử dụng ít hơn 5MB (kiểm tra trong taskmanager) với không có gì nghiêm trọng chạy trong nền).

  2. Nếu bộ nhớ quá phân mảnh để phân bổ khối mới (không, khối lượng lớn nhất mà tôi từng phân bổ sẽ là khoảng 1KB và không được thực hiện quá 100 lần trước khi xảy ra sự cố).

Dựa trên những mô tả này, tôi không thực sự có bất kỳ nơi nào có thể ném bad_alloc.

Tuy nhiên, ứng dụng tôi đang chạy chạy nhiều hơn một chuỗi, có thể có thể góp phần gây ra sự cố. Bằng cách kiểm tra tất cả các đối tượng trên một sợi đơn, mọi thứ dường như hoạt động trơn tru. Điều duy nhất mà tôi có thể nghĩ về điều đó đang diễn ra ở đây có thể là một loại tình trạng chủng tộc gây ra bằng cách gọi mới() ở nhiều nơi cùng một lúc, nhưng tôi đã thử thêm các mutex để ngăn chặn hành vi đó không có hiệu lực.

Vì chương trình là vài trăm dòng và tôi không biết vấn đề nằm ở đâu, tôi không chắc chắn về những gì, nếu có, đoạn mã để đăng. Thay vào đó, tôi đã tự hỏi liệu có bất kỳ công cụ nào giúp tôi thử nghiệm loại điều này hay không, hoặc nếu có bất kỳ chiến lược chung nào có thể giúp tôi giải quyết vấn đề này.

Tôi đang sử dụng Microsoft Visual Studio 2008, với Poco để phân luồng.

Trả lời

16

Một vấn đề có thể là, trong khi bạn đề cập rằng chương trình được sử dụng ít hơn 5MB, bạn không đề cập bao nhiêu không gian nó đang cố gắng để phân bổ. Bạn có thể có một số điều kiện chủng tộc làm hỏng giá trị mà bạn sử dụng để xác định kích thước phân bổ và có thể cố gắng phân bổ 37TB hoặc vô nghĩa.

Không có khả năng đặc biệt, tôi cho là, nhưng đáng để kiểm tra.

+0

Thực ra đó là vấn đề ... không biết chính xác vấn đề là ở đâu, nhưng có rất nhiều biến bị biến mất lang thang xung quanh ở những nơi kỳ lạ - có vẻ như có một điều kiện chủng tộc ở đâu đó. Cảm ơn bạn! – Salami

+0

Đó là trường hợp của tôi ... Tôi nghĩ tôi đang gọi 'new char [_len] ', nhưng tôi đã gọi' new char [len]' khi 'len' không được khởi tạo nhưng có lẽ một số lượng lớn. Nó thực sự giúp suy nghĩ về bao nhiêu không gian tôi yêu cầu và để xem xét các giá trị gần hơn. Cảm ơn câu trả lời. – flcoder

3

ít làm rõ:

Mỗi quá trình trong các cửa sổ bị 4GB bộ nhớ ảo, trong đó có 2GB là cho không gian sử dụng và còn lại cho không gian hạt nhân. RAM 4GB sẽ không đóng góp vào bộ nhớ ảo nhưng nó dành cho bộ nhớ vật lý.

Trong bộ nhớ 2GB, tất cả EXE, DLL được tải và hầu như không có 1.6 - 1.7 GB để cấp phát bộ nhớ. Trong bộ nhớ này nếu không có bộ nhớ tiếp giáp để phân bổ thì việc cấp phát bộ nhớ không thành công.

+0

bạn có biết về hệ thống linux/unix phân bổ bao nhiêu không? – anish

20

bad_alloc cũng có thể được ném khi bạn có lỗi ghi đè các con trỏ mà heap sử dụng để quản lý nhóm bộ nhớ mà nó sử dụng để phân bổ.

Nguyên nhân phổ biến nhất của điều đó là bạn đang viết qua phần cuối của một khối bộ nhớ được phân bổ, (hoặc trước khi bắt đầu, nhưng điều đó ít phổ biến hơn). Gần như phổ biến là viết vào một khối bộ nhớ sau khi nó đã được giải phóng. Điều này được gọi là tham nhũng đống.

Ngoài ra, tôi nên lưu ý, quy trình 32 bit trong Windows có tối đa 2GB không gian địa chỉ (3GB cho các chương trình nhận biết địa chỉ lớn). Điều này là bất kể bạn đã cài đặt bao nhiêu RAM, bộ nhớ là ảo và phân bổ không thành công cho đến khi bạn hết dung lượng địa chỉ, ngay cả khi bạn chỉ có RAM 1GB.

Đây là một cuộc thảo luận tốt về tham nhũng bộ nhớ trong C++ http://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm

+0

Cảm ơn bạn đã cung cấp thông tin tại đây. – Salami

1

bad_alloc cũng có thể được ném bởi mã khác.

Tôi đã nhìn thấy nó được sử dụng bởi một nhóm bộ nhớ hạn chế được thiết kế để sử dụng với các thùng chứa STL. Khi giới hạn kích thước được nhấn, nó đã ném bad_alloc và phần mềm chỉ phải xử lý nó.

0

Tôi đã thực sự gặp vấn đề này trước đó và nó đã được sửa chữa bằng cách làm sạch và xây dựng lại dự án. Luôn luôn đáng thử khi bạn có hành vi kỳ lạ (trừ khi nó là một dự án lớn mà phải mất nhiều giờ để biên dịch).

Các vấn đề liên quan