-1

ここにいる誰かが、MSVC 2010 のバグである可能性があると私が考えるものを理解してくれることを願っていました。

私はこのコードを持っています(はるかに大きなプロジェクトの一部として):

namespace MyNamespace{

class Foo{
   //snip
   QPointer<MyNamespace::Baz> :: x;
};

class Baz{
   //snip
};

//snip
Foo::Bar(){
   x = new MyNamespace::Baz();
   ThisFunctionWillSegfaultIfXIsNull(x);
   //snip
}

繰り返しますが、これは、cmake、qt、およびその他のエキサイティングなものが多数含まれる、はるかに大きなプロジェクトの一部であることを覚えておいてください。

これをデバッガーでトレースしてきました。このプロジェクトをデバッグ モードでコンパイルすると、すべてが期待どおりに進みます。ただし、これをリリース プロジェクトとしてコンパイルすると、x の値は 0x0000000000000000 になります。

また、MSVS デバッガー (まだリリース モード) でこれをトレースすると、いくつかの興味深いことが起こります。

  1. Baz のコンストラクターは実際に呼び出され、「this」には Baz のコンストラクター内に有効なメモリ位置があります。

  2. コンストラクターから戻った後Foo::Bar()(おそらく "Foo") の値は、Baz のコンストラクター (おそらく "Baz") 内の "this" の値と同じになります。

  3. 明らかにメモリ アドレスが変更されただけですが、Foo のデータは失われていないようです。

  4. "This" (Foo として) は、コンストラクター中に割り当てられたすべての正しいデータを含む MyNamespace::Baz 型の新しいデータ メンバーを魔法のように成長させます。

どうやらコンパイラの最適化が非常に神秘的な何かを引き起こしているようです。繰り返しますが、これはリリース モードでのみ発生するようです。これにより、A) オプティマイザが違いを生み、B) 実際に何が起こっているかについての詳細情報を取得することが難しくなっていると思います。

誰もこれを見たことがありますか?ここで何が起きてるの?X が null であるため、次の関数で segfaulting を停止するにはどうすればよいですか?

4

1 に答える 1

1

問題は別の場所にあります。デバッガーがトリックを実行する以外に (リリース モードでよくあることですが)、newを返すことはできませんNULL。割り当てが失敗した場合、例外がスローされますが、返されることはありませんNULL

これは、いくつかのデバッグ ステートメントで確認できます。

if (x)
   std::cout << "x is not NULL";
于 2012-09-06T17:50:50.187 に答える