2013-02-06 17 views
10

Tôi đang làm việc trên thư viện được liên kết động (DAC) quan trọng về hiệu năng, cũng nên có kích thước nhị phân tương đối nhỏ. Vì nó không rõ ràng ném bất kỳ ngoại lệ nào, tôi muốn tắt hoàn toàn hỗ trợ ngoại lệ. Tuy nhiên, có một ngoại lệ (chơi không mong muốn): khi hết bộ nhớ (OOM), tôi phải báo cáo mã lỗi cho ứng dụng để nó có cơ hội xử lý mọi thứ một cách duyên dáng. Cơ sở mã quá lớn để kiểm tra từng phân bổ riêng lẻ và truyền bá lỗi và chứa mã bên ngoài mà tôi không nên chạm vào. Vì vậy, tôi muốn bắt OOM ngoại lệ trong các chức năng xuất khẩu của DLL của tôi. Một thử nghiệm nhanh cho thấy rằng khi vô hiệu hóa ngoại lệ C++ trong Visual C++ 2010 (tức là không có/EHa,/EHsc hoặc/EHs flags), nó vẫn nhảy đến một khối catch (std :: bad_alloc &) khi phân bổ quá nhiều bộ nhớ .Làm thế nào để đảm bảo sự vững chắc ngoài bộ nhớ với các ngoại lệ C++ bị vô hiệu hóa (VS2010)?

Vì vậy, có vẻ như nó hoạt động như mong muốn. Tuy nhiên, tôi nhận được cảnh báo cấp 1 sau: "C4530: C + + xử lý ngoại lệ được sử dụng, nhưng thư giãn ngữ nghĩa không được kích hoạt. Xác định/EHsc". MSDN nói rằng "một đối tượng với lưu trữ tự động trong khung, giữa các chức năng làm ném và chức năng bắt ném, sẽ không bị phá hủy".

Chính xác thì tôi sẽ mất gì ở đây? Bạn nên để mọi thứ ở trạng thái không xác định, miễn là mọi thứ được tạo ra thông qua thư viện có thể bị xóa và ứng dụng có thể bắt đầu lại (nếu nó chọn). Có một nguy cơ lớn rò rỉ bộ nhớ mà không thể được phục hồi?

Dll có sử dụng một bộ nhớ riêng biệt không? Và nếu vậy, tôi có thể thanh lọc nó mà không yêu cầu ứng dụng dỡ bỏ DLL không? Tôi có thể dễ dàng làm cho thư viện của tôi bỏ qua bất kỳ cuộc gọi hàm (xuất khẩu) nữa cho đến khi ứng dụng thực hiện reinitialization.

Cảm ơn lời khuyên của bạn.

+0

* Dll có sử dụng một bộ nhớ riêng biệt không? * Http://stackoverflow.com/questions/10820114/do-statically-linked-dlls-use-a-different-heap-than-the-main-program – thang

+0

* Và nếu vậy, tôi có thể thanh lọc nó mà không yêu cầu ứng dụng dỡ bỏ DLL không? * Vâng, chỉ cần xóa nội dung đó khỏi công cụ mới và miễn phí từ malloc. – thang

+1

Không có xử lý ngoại lệ có nghĩa là các đối tượng được tạo trên ngăn xếp (và bên trong một hàm tạo không thành công) sẽ không bị hủy. Nếu bạn chỉ cần thoát ra khi 'bad_alloc' xảy ra, thì bạn ổn với điều đó, tôi giả sử [miễn là bạn không có tài nguyên lạ mà không được dọn dẹp với chương trình thoát - nhưng hầu hết nên]. Nếu bạn muốn "tiếp tục" sau 'bad_alloc', thì mã sẽ cần phải theo dõi các đối tượng và phá hủy tất cả các đối tượng được tạo trong các khung ngăn xếp giữa' throw' và 'catch'. Bạn có thể thử nghiệm bằng cách viết một số mã nhỏ có bản in trong destructors. –

Trả lời

1

Một vài sơ bộ:

Tôi không biết nếu ném một ngoại lệ mà không cần xử lý ngoại lệ cho phép là hành vi không xác định hoặc không theo tiêu chuẩn, nhưng bạn chắc chắn sẽ không có được chồng gọi ươm/destructor từ đối tượng của bạn trên ngăn xếp.

Nếu bạn đang viết mã kiểu C++ sử dụng RAII cho mutexes, tệp, bộ nhớ, v.v ..., đây là một điều rất tệ.

Di chuyển trên đó, và giả mã của bạn về cơ bản là mã C-style:

1) Nếu bạn đang liên kết tĩnh để thư viện runtime C, DLL của bạn sẽ không chia sẻ một đống với ứng dụng chính của bạn. Việc dỡ bỏ DLL sẽ giải phóng bộ nhớ bị rò rỉ - nhưng một lần nữa, hãy quan tâm đến các tài nguyên khác.

2) Nếu bạn đang liên kết động với thời gian chạy C (khá phổ biến), thì bạn đang chia sẻ một đống. Bạn sẽ phải có một cách để tự giải phóng bất kỳ bộ nhớ nào được cấp phát từ DLL.

Có bản thân mình bỏ qua quá nhiều với các vấn đề biên DLL, tôi khuyên bạn nên đánh giá nhanh để xem bạn đang trả tiền cho điều gì để loại trừ ngoại lệ. Tùy thuộc vào nền tảng và trình biên dịch của bạn, ngoại lệ không được biết đến có thể có tác động hiệu suất khá không đáng kể.

+0

Nó không phải là mã kiểu C, và một phần quan trọng của nó không nằm trong tầm kiểm soát của tôi. Trong khi tôi tin tưởng mã bên thứ ba này trong hoạt động bình thường, khi một ngoại lệ OOM được ném, tôi không nghĩ rằng tôi có thể đưa ra bất kỳ giả định nào, bất kể việc xử lý ngoại lệ có được bật hay không. "_Bạn sẽ phải có cách để tự giải phóng mọi bộ nhớ được cấp phát từ DLL._" Đó chính xác là câu hỏi của tôi. :-) –

+0

Xin lỗi, nhưng tôi nghĩ rằng thực sự không có cách nào để làm những gì bạn muốn. Để đạt được "phát hành thủ công từ DLL" trong các hệ thống kiểu plugin của riêng tôi, tôi yêu cầu tất cả mã máy khách cấp phát bằng cách sử dụng một thường trình phân bổ tùy chỉnh mà nguồn cung cấp cốt lõi của tôi cho DLL. Liên kết này cho phép lõi thả một DLL giống như bạn muốn. Nhưng nếu bạn không thể thực thi điều này, thì tôi không nghĩ rằng nó có thể được thực hiện. – Stephen

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