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. その理由は、コンストラクタが呼び出された直後に003デストラクタが呼び出されるためです。myAllocatorこれは、が破棄されているため、myAllocatorline では無効であることを意味します。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

最初の例でコンパイラがデストラクタ呼び出しを生成するのはなぜですか

4

2 に答える 2

1

この行で

Allocator myAllocator = shm.allocator();

次の操作を行っています。

  1. Allocator新しい一時オブジェクトを構築する
  2. Allocatorrhs が一時的な場所のコピー コンストラクターを呼び出します
  3. ポイント1で作成された一時オブジェクトを破棄する

考慮されておらず、SIG SEV を引き起こす可能性のある 2 つの操作があります: コピー コンストラクタとデストラクタです。

于 2012-12-20T12:00:12.360 に答える
1

Allocator myAllocator = shm.allocator();はコピーの初期化であり、( からのosal_allocator*) 変換コンストラクターと (一時的な からの) コピー コンストラクターの呼び出しを伴いAllocatorます。呼び出されるデストラクタは、一時Allocatorオブジェクトのデストラクタです。

クラッシュの原因としては、コピー コンストラクターの欠落、または でのコピー コンストラクターの実装が不十分であることが考えられAllocatorます。

これは、初期化を次のように変更するというあなたの主張によって裏付けられています

Allocator myAllocator( shm.allocator );

動作します-これは、コピーが含まれていないためです-変換コンストラクターが直接呼び出され、一時オブジェクトは作成されません。

「3つのルール」を読んでください。

基本的に、クラスがデストラクタ、コピー コンストラクタ、またはコピー代入演算子のいずれかを必要とする場合 (通常、クラスがリソースを管理する場合)、その 3 つすべてが必要になります

于 2012-12-20T11:54:49.060 に答える