2010-08-04 14 views
7

Trên Linux, tôi có một số mã C++ được tạo từ một thư viện tĩnh định nghĩa một biến toàn cầu. Một cá thể duy nhất của biến toàn cầu này được chia sẻ giữa hai thư viện được chia sẻ tham chiếu đến biểu tượng của nó.Trên Linux, tại sao trình phá hủy chạy hai lần trên cá thể chia sẻ của biến toàn cục trong C++?

Khi quá trình tắt và giai đoạn kết thúc tĩnh được chạy, tôi thấy rằng hàm hủy trên phiên bản dùng chung này được chạy hai lần! Có lẽ một lần cho mỗi thư viện là mỗi lần tải.

Câu hỏi này liên quan chặt chẽ đến câu hỏi khác tôi đã thấy gần đây tại đây: related question. Điều này nghe giống như hành vi tương tự, nhưng không có thảo luận về lý do tại sao nó đang xảy ra.

Có ai biết giải thích lý thuyết đằng sau hành vi này không?

+0

Nó chỉ được chạy một lần cho mỗi biến bởi trình biên dịch tạo mã. Hãy thử lấy địa chỉ của biến khi hàm hủy được chạy để xác minh rằng nó là cùng một đối tượng. –

+0

Có lẽ bạn đã lưu một con trỏ tới đối tượng trong một số lớp con trỏ thông minh, mà cố gắng phá hủy nó. –

+0

Vì vậy, toàn cầu được định nghĩa trong (một đơn vị biên dịch) chỉ một trong các thư viện? – Thomas

Trả lời

2

Nếu bạn lấy một con trỏ khỏa thân và đặt nó vào một con trỏ thông minh (hai lần), nó sẽ hủy hai lần, một lần cho mỗi lần truy cập vùng chứa xuống bằng không.

Vì vậy, nếu bạn chuyển con trỏ trần vào cả hai thư viện, điều đó sẽ thực hiện. Mỗi người đặt nó vào một đối tượng con trỏ được chia sẻ và mỗi đối tượng đó đều hủy diệt. Nếu bạn có thể thấy backtrace stack trong dtor, điều đó sẽ cho thấy nó xảy ra trong cả hai thư viện.

+1

Sử dụng bất kỳ trình sửa lỗi thông thường nào, bạn nên dễ dàng kiểm tra lại dấu vết cuộc gọi và tìm ra ai đang gọi hàm hủy này. – Vargas

0

C++ có một quy luật gọi là "Một Definition Rule":

Mỗi chương trình sẽ chứa chính xác một định nghĩa của tất cả các chức năng phi inline hoặc đối tượng được sử dụng trong chương trình đó; không cần chẩn đoán. Định nghĩa có thể xuất hiện rõ ràng trong chương trình, nó có thể được tìm thấy trong thư viện chuẩn hoặc thư viện do người dùng định nghĩa, hoặc (khi thích hợp), nó được định nghĩa ngầm định (xem 12.1, 12.4 và 12.8).

Wikipedia có số article giải thích điều này chi tiết hơn.

Bạn chưa đăng mã trong câu hỏi của mình, vì vậy tôi không chắc chắn về trường hợp của bạn, nhưng trong the question you linked to, ví dụ trong câu hỏi đã xác định cùng một biến trong hai thư viện được chia sẻ. Điều này vi phạm "Quy tắc một định nghĩa", rõ ràng chiến lược hoàn thiện của liên kết động phụ thuộc vào, khiến cho hàm hủy được gọi hai lần.