2012-12-20 90 views
0

給下面的函數:爲什麼在調用隱式類型轉換構造函數後直接析構函數?

osal_allocator* SharedMemoryManager::allocator();I 

osal_allocator是一個 'c' 的結構,含函數指針。

而包裝類,提供了下面的構造:

Allocator::Allocator(osal_allocator*); 

函數作出如下呼叫:

001 SomeFunc(SharedMemoryManager* shm) 
002 { 
003 Allocator myAllocator = shm.allocator(); 
004 
005 myAllocator.doSomething(); 
006 
007 // stuff 
008 } 

代碼失敗,出現SIG SEGV。原因是在線003myAllocator的析構函數在其構造函數被調用後立即被調用。這意味着myAllocator在線路005上無效,因爲它已被銷燬。

(注意:默認構造函數沒有被調用,也沒有任何賦值運算符)。

如果線003改爲:

003 Allocator myAllocator(shm.allocator); 

功能正常工作,與myAllocators的析構函數沒有被調用,直到它超出範圍。

不幸的是,我無法用一個簡單的例子重現此問題。

我使用:

g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3) 

通過以下選項:

c++ -MD -D__LINUX__ -g -ansi -Wall -Wextra -Wformat -Wno-format-security -Woverloaded-virtual -Iinc 

爲什麼編譯器生成的析構函數調用的第一個例子

+0

您的問題的答案是,您需要正確並正確地遵循**三條規則**。 –

+0

請發佈*實際的最小完整代碼*,而不僅僅是一些近似值。你的代碼不會編譯。 –

+0

「爲什麼編譯器爲第一個示例生成無效代碼」的可能性非常高,事實並非如此。 – PlasmaHH

回答

1

這一行

Allocator myAllocator = shm.allocator(); 

你正在做以下操作:

  1. 構造一個新的Allocator臨時對象
  2. 呼叫的Allocator拷貝構造函數在RHS是臨時
  3. 銷燬在第1點創建的臨時對象

有兩種可能的操作,您不會考慮並可能會導致SIG SEV:複製構造函數和析構函數。

1

Allocator myAllocator = shm.allocator();是拷貝初始化和涉及轉換構造函數(從osal_allocator*)和複製構造函數uctor(來自臨時Allocator)。被調用的析構函數是臨時的Allocator對象的析構函數。

該崩潰可能是由於缺少拷貝構造函數或在Allocator中執行得不好的拷貝構造函數。

這是由你的要求備份,改變初始化

Allocator myAllocator(shm.allocator); 

作品 - 這是因爲沒有參與的複製 - 轉換構造函數直接調用,沒有創建臨時對象。

Read up on "the rule of three".

基本上,如果一個類或者要求一個析構函數,拷貝構造函數或拷貝賦值運算符(當一個類管理資源,這通常是這種情況),它需要他們三個都的。

+0

Ruke of Three - 這就是爲什麼我試圖重現問題的工作原理和真正的代碼不 - 它遵循3的規則,但Allocator的代碼(不是我的)缺少一個拷貝構造函數.... – mark

+0

@mark這肯定是問題,是的。 –

相關問題