2010-08-13 42 views
8

Tôi đang làm việc trên một ứng dụng Win32 C++ trong Visual studio.Tai nạn hủy diệt

Trong một trong các tệp nguồn, tôi có đối tượng chung như dưới đây.

TestClass tObj; 

int main() //Execution starts here 
{ 
} 

TestClass được định nghĩa trong DLL khác như dưới đây.

struct Source 
{ 

}; 

class TestClass 
{ 
    list<Source> sourceList; 
    public: 
     TestClass() {} 
     ~TestClass() {} 
}; 

Trong khi ứng dụng của tôi đang chạy, nếu tôi cố gắng để đóng ứng dụng một cách rõ ràng, bằng cách đóng cửa sổ giao diện điều khiển, nó được đâm trong TestClass destructor. Hiển thị Callstack CrtIsValidHeapPointer không thành công.

Xin giúp tôi giải quyết vấn đề này.

+0

Sử dụng bốn dấu cách để thụt lề mã và không có ký tự bình thường. –

+1

Bạn đã xây dựng exe và DLL với cùng thời gian chạy C++ chưa? – Mark

+0

Có tôi đã xây dựng cả hai với Visual studio. Chỉ loại cấu hình khác nhau. Một là exe và khác là cấu hình DLL trong cài đặt dự án. – bjskishore123

Trả lời

4

Đảm bảo bạn xây dựng bot EXE và DLL có cùng thời gian chạy, tốt nhất là với thời gian chạy động.

+0

Sự cố được giải quyết bằng cách sử dụng cùng thư viện thời gian chạy trong exe và dll. Cảm ơn tất cả các bạn đã giúp tôi. – bjskishore123

1

Đó là sự cố trong trình phá hủy, một ngoại lệ đang được ném từ trình phá hủy đang kêu gọi chấm dứt và làm hỏng ứng dụng của bạn. Uncaught exceptions

Có hai tình huống trong đó một trình phá hủy được gọi. Đầu tiên là khi một đối tượng bị phá hủy trong các điều kiện "bình thường", ví dụ: khi vật thể nằm ngoài phạm vi hoặc bị xóa một cách rõ ràng. Thứ hai là khi một đối tượng bị phá hủy bởi cơ chế xử lý ngoại lệ trong phần stack-unwinding của tuyên truyền ngoại lệ. Bạn phải viết hàm hủy của bạn dưới giả định bảo thủ rằng một ngoại lệ được kích hoạt, bởi vì nếu kiểm soát để lại một destructor do một ngoại lệ trong khi ngoại lệ khác đang hoạt động, C++ gọi hàm chấm dứt

+0

Đối tượng toàn cầu đang được xây dựng trước khi main() được gọi. Vì vậy, tôi nghĩ rằng, sự hủy diệt của nó đang xảy ra sau khi thoát(). Lúc đó, danh sách đầu nguồn danh sách mà STL sử dụng nội bộ, không hợp lệ tại thời điểm giải phóng. Do đó CrtIsValidHeapPointer không thành công. – bjskishore123

+0

Câu hỏi đặt ra là: tại sao đầu nguồn SourceList không hợp lệ? Nếu exe của bạn và DLL được xây dựng đúng với runtimes tương thích, sau đó mã này sẽ làm việc tốt. Thời gian chạy sẽ làm sạch các đối tượng toàn cầu trước khi vùng heap được giải phóng. –

+0

Sự cố được giải quyết bằng cách sử dụng cùng thư viện thời gian chạy trong exe và dll. Cảm ơn tất cả vì đã giúp đỡ tôi. – bjskishore123

1

đối tượng toàn cầu được khởi tạo và phá hủy bởi Thời gian chạy C. Chúng được khởi tạo trước khi main được gọi và bị hủy sau khi trả về.

Lỗi này có thể do một thứ gì đó đang được truy cập từ trình phá hủy TestClass của bạn (hoặc gián tiếp từ trình phá hủy Source). Mã destructor đang truy cập bộ nhớ không hợp lệ (hoặc bộ nhớ đã được giải phóng).

Thứ tự khởi tạo và hủy các biến toàn cục không được xác định và thường là nguồn của lỗi khi chấm dứt ứng dụng. Nếu có các globals khác có thể dọn dẹp hoặc sửa đổi các tài nguyên được tham chiếu bởi TestClass, thì đây có thể là thủ phạm.

+0

Tôi không thêm bất kỳ nút nào vào danh sách nguồn (danh sách ). Danh sách trống tại thời điểm cuộc gọi hủy. Nhưng vẫn còn, Danh sách STL sẽ có một con trỏ đầu ẩn bên trong. Trong khi cố gắng giải thoát điều đó, nó bị rơi. – bjskishore123

+0

CRT (s) nào bạn đang xây dựng EXE và DLL chống lại? –

0

Dll và EXE có được sử dụng cùng một căn chỉnh (gói pragma) không?

9

Vấn đề của bạn là khác nhau thiết lập trình biên dịch/mối liên kết giữa .exe và .dll đang gây ra một cách hiệu quả các .dll và .exe để được sử dụng hiện thực khác nhau của thư viện tiêu chuẩn:

  • Bạn phải sử dụng cùng một các cờ tiền xử lý * để xây dựng cả tệp .exe và .dll, nếu không thì mỗi nhị phân sẽ biên dịch với các triển khai khác nhau một cách tinh tế.
  • Bạn phải liên kết cả tệp .exe và .dll với thời gian chạy động. Các tệp nhị phân được liên kết tĩnh với thời gian chạy có được vùng heap riêng của chúng - và bạn sẽ phân bổ trên một đống và cố gắng giải phóng trên một vùng khác.

Để khắc phục điều này, hãy chuyển đến Project > Properties > Configuration Properties > C/C++ > Code Generation và thay đổi tùy chọn thư viện thời gian chạy thành Multi-threaded Debug DLL (/MDd). Bạn phải làm điều này cho cả dự án .exe và dự án .dll.

Kể từ Visual Studio 2010, một số loại lỗi này sẽ được phát hiện tại thời gian liên kết bằng cách sử dụng #pragma detect_mismatch.

* Đối với tất cả những lá cờ Preprocessor rằng có bất kỳ tác của thư viện thực hiện tiêu chuẩn

+0

'+ 1' từ tôi cho câu trả lời toàn diện này. @ bjskishore123: Vui lòng đọc [FAQ] (http://stackoverflow.com/faq). Bạn được khuyến khích chấp nhận câu trả lời mà bạn cảm thấy đã giúp bạn nhiều nhất để giải quyết vấn đề của bạn. – sbi

0

cố gắng để làm cho constructor của bạn và destructor không nội tuyến, nó có thể giúp. Nếu ctor và dtor không phải là inline, cả hai sẽ được tạo ra thay mặt cho dll, vì vậy việc xây dựng và hủy bỏ danh sách <> sẽ được thực hiện với cùng một thư viện thời gian chạy. Nói chung, hãy cố gắng tránh đi qua các obl stl mờ đục trên các ranh giới dll. Tốt hơn là đóng gói chúng thành các thành viên privatte vào các lớp của riêng bạn và cung cấp các phương pháp không được gạch chân để thao tác các thành viên như vậy

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