2011-11-12 2 views
8

Lỗi này đã làm phiền tôi khoảng hai ngày: khi chạy mã tôi có lỗi thời gian chạy "chấm dứt được gọi mà không có ngoại lệ hoạt động \ n Bị hủy bỏ ",tại sao?Lỗi thời gian chạy sau có nghĩa là: "chấm dứt được gọi là không có ngoại lệ hoạt động n Bị hủy"

Tôi cố tìm mã và tìm dòng có thể thoát mã "xx = new int [num]", chữ số trong trường hợp thử nghiệm của tôi là khoảng 640000 (bộ nhớ 64MB đến mới). khi tôi đặt num nhỏ hơn nhiều là 10, nó là OK, nhưng mã của tôi nhận được một câu trả lời sai thời gian này.

Tôi cố xóa tất cả điều khoản "try/catch" nhưng vẫn gặp lỗi này.

Ngoài ra tôi // tất cả hàm gọi mệnh đề "xx = new int [num]", lỗi vẫn tồn tại và lần này tôi xác định mã có thể thoát là "vòng lặp" bình thường.

Tất cả trường hợp đã thông qua trình biên dịch, bạn đã từng gặp lỗi này khi chạy mã của mình chưa? Cảm ơn bạn!

Tôi // một số khoản xóa và nhận được báo lỗi dưới đây: * glibc phát hiện * ./ESMF_RegridWeightGen: munmap_chunk(): con trỏ không hợp lệ: 0x00000000005cd376 *

+1

Hãy thử đặt một 'thử/catch' chặn xung quanh toàn bộ cơ thể' main' của bạn và xem nếu có bất kỳ trường hợp ngoại lệ nào cả ... –

+0

Bạn có một mẫu mã nhỏ thể hiện vấn đề này không? –

+0

bạn có nhiều chủ đề không? – neagoegab

Trả lời

4

Các "chấm dứt mà không một ngoại lệ hoạt động" tin nhắn là một gợi ý rằng, tại một số điểm trong chương trình của bạn, xử lý ngoại lệ đã bị hỏng.

Phân bổ bộ nhớ có lẽ là nguyên nhân chính, nhưng có thể không phải là trang web lỗi. Việc phân bổ lớn sẽ ném một std :: bad_alloc exception, và ngoại lệ này được xử lý không chính xác ở đâu đó.

Để xác nhận lý thuyết, chèn một dòng như

throw std::logic_error("Foo"); 

trên việc phân bổ, điều này sẽ gây ra lỗi là tốt.

Tôi đã gặp hai nguyên nhân phổ biến cho việc này:

  • chương trình mingw Multithreaded biên soạn mà không có cờ đúng
  • Một destructor được gọi như là một phần của quá trình ươm cây rơm đã ném một ngoại lệ

Bạn sẽ có thể chẩn đoán điều kiện sau bằng trình gỡ lỗi. Một dấu vết ngăn xếp của ứng dụng của bạn (ví dụ: thu được bằng cách chạy nó trong gdb) sẽ giúp ích rất nhiều.

+0

khoảng 2.5GB phân bổ là gì? 640000 * sizeof (int) – neagoegab

+2

@neagoegab: Lần trước tôi đã kiểm tra, sizeof (int) <10, vì vậy 640,000 * sizeof (int) <6,400,000 <6,4 MB. Nó có thể là quá lớn và có thể ném một std :: bad_alloc. Mà nên kết quả, tại tồi tệ nhất, trong một cuộc gọi chấm dứt in std :: bad_alloc, không phải trong "chấm dứt được gọi là không có một ngoại lệ hoạt động". Có một vấn đề tồi tệ hơn ở đâu đó, và phân bổ quá lớn của anh ta chỉ kích hoạt nó. – thiton

+0

có, bạn đang phải – neagoegab

7

Tôi gặp phải điều này khi tôi cố gắng sử dụng lệnh ném; bên ngoài một điều khoản bắt. Việc không hoạt động lại và thông báo lỗi đó được hiển thị.

+0

Cảm ơn, điều đó đã cứu tôi ngay bây giờ. – Etherealone

18

Khi tôi đã nhìn thấy lỗi này, nguyên nhân là do hủy đối tượng chuỗi trước khi chuỗi được đóng gói đã thoát.

+1

Nó có thể không có gì để làm với các sợi ở tất cả. Bạn có thể có 'std :: thread foo (...)' trong một khối cục bộ và ném một ngoại lệ sau khi bạn bắt đầu luồng. Trước khi ngoại lệ của bạn bị bắt, destructor luồng xảy ra, và nó gọi 'std :: terminate()', điều này làm cho khó gỡ lỗi ngoại lệ thực sự! –

1

Với MinGW, thêm tùy chọn biên dịch -mthreads để gcc giải quyết vấn đề này.

Từ the gcc manual:

-mthreads

Hỗ trợ xử lý ngoại lệ thread-an toàn trên Mingw32. Mã dựa vào xử lý ngoại lệ thread-safe phải biên dịch và liên kết tất cả mã với tùy chọn -mthreads. Khi biên dịch, -mthreads định nghĩa -D_MT; khi liên kết, nó liên kết trong một thư viện helper thread đặc biệt -lmingwthrd mà dọn dẹp cho mỗi thread xử lý dữ liệu ngoại lệ.

2

Giống như Gearoid Murphy cho biết lỗi xảy ra khi đối tượng thread destructed trước khi chức năng thread riêng của mình đã được thực hiện đầy đủ. Tôi phát hiện ra lỗi này sử dụng thư viện tinythread (http://tinythreadpp.bitsnbites.eu/):

Trước:

#include "tinythread.h" 
... 
void fork_thread(void (*function_pointer)(void * arg), void * arg_pointer) { 
    tthread::thread t(function_pointer, arg_pointer); 
    // t is destructed here, causing the "terminate called ..." error 
} 

Sau:

#include "tinythread.h" 
... 
void fork_thread(void (*function_pointer)(void * arg), void * arg_pointer) { 
    tthread::thread * t = new tthread::thread(function_pointer, arg_pointer); 
    // now the new thread object is not destructed here, preventing 
    // the "terminate called ..." error. Remember that because thread 
    // object must now be destructed explicitly (i.e. manually) with delete 
    // call you should store the pointer t to a vector of thread pointers 
    // for example. 
}