6

クラス A と、A から派生したクラス B があるとします。ここで、dynamic_cast を使用して const A* (「a」と呼ばれる) を B* にキャストしたいと考えています (以下を参照)。「a」が本当に B* だった場合、結果のオブジェクト ポインターは問題ないはずです。「a」が B* でない場合は、NULL になります。

const A* a = new B();
const B* b = dynamic_cast<const B*>(a);

何らかの理由で、dynamic_cast 操作によって SEGFAULT が発生します。「a」がNOT NULLの場合、どうすればそれが起こりますか? 変換に問題があった場合、SEGFAULT ではなく、dynamic_cast が NULL ポインターを返すと思います。「b」にアクセスしようとして動的キャストが失敗した場合にのみ、SEGFAULT を取得する必要があります。「b」へのアクセスはまだ試していません。

では、これはどのように起こりますか?上記のコードで、dynamic_cast を SEGFAULT にする原因となるものはありますか?

前もって感謝します :-)

編集: GDB を介して実際のプログラムを実行すると、次の出力が得られます。

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) where
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff6c0e612 in __cxxabiv1::__dynamic_cast (src_ptr=<optimized out>, 
src_type=0x4fa6b0, dst_type=0x516bb0, src2dst=0)
at /var/tmp/portage/sys-devel/gcc-4.6.3/work/gcc-4.6.3/libstdc++-v3/libsupc++/dyncast.cc:61

出力の次の行は、動的キャストを行うコード内の行を指しています。

4

3 に答える 3

17

dynamic_cast の使用時にクラッシュを引き起こす可能性がある理由

  • ポインタは空きメモリ ブロックを指します。
  • pointer が非ポリモーフィック型を指しています。
  • pointer は多相型を持つオブジェクトを指していますが、RTTI を無効にしてコンパイルされた外部ライブラリに存在します。
  • ポインターは、保護例外 (ガード ページやアクセスできないページなど) を引き起こす可能性のあるメモリ アクセスを指しています。

これらのケースのいずれかに該当するかどうかを確認してください。

于 2013-01-09T18:30:25.757 に答える
2

私のような他の人にとっては、キャスト元のオブジェクトと同じ変数名を誤ってキャストオブジェクトに付けた可能性があります!

A *name = new B();
B *name = dynamic_cast<B*>(name);

これは、このような明白なコードでは明らかに間違っていますが、変数が分散され、キャストが難読化されているため、このような実際の間違いを見つけるのははるかに困難です!

于 2016-04-21T15:34:46.783 に答える
0

私はこれを一度手に入れました... ポインターの初期化に失敗したためで、ランダムなゴミを指していました。

于 2016-10-20T07:57:12.210 に答える