10

アプリケーションで非常に奇妙な動作に直面しています。

自分の状況を説明してから、何が問題なのかを説明します。

状況

次のようなシグネチャを持つメソッドがあります。

const StructureDef *getStructure(const std::string &theme, int index);

そして、このコードでそれを呼び出します。

const StructureDef *sDef = 0;
do 
{
    sDef = ss->getStructure(theme, rand() % ss->availableStructureCount());
} while (!sDef);

との組み合わせによっては、getStructureメソッドの戻り値が になる可能性があるため、この do-while 構造を使用しています。つまり、基本的には、有効な構造が得られるまでランダムな構造を尋ねます。(詳しく知りたい方はスクリーンショットをご覧ください。)NULLthemeindex

std::vector<StructureDef>メソッドは、 it を使用して を反復処理し::iteratorます。また、各 StructureDef について、構造がそのテーマに属しているかどうかを確認します。その場合は、カウンターをポストインクリメントし、要求されたインデックスと等しいかどうかを確認します。このような:

// inside the loop
if (i++ == index)

これが成功すると、現在の値StructureDef *が返されます。

return sDef;

何がうまくいかないのか

私はXCode 4.4を使用しています。これは、基本的にgdbである、何が起こっているかを段階的に確認するためのデバッガーです。

最初に説明した方法でStructureDef *、自分のニーズに合った a を見つけます。したがって、そのポインターを返します。デバッガーに戻る直前のスクリーンショットを次に示します。

デバッガーのリターンポイント

(for ループの後の行は単にreturn 0;)

ここでポインタは、 の正しいインスタンスが配置されている場所をsDef *指しています。0x1d563270StructureDef

次のスクリーンショットは、そのメソッドを呼び出したコード部分で取得したものです。

発信者が住所を間違える

ご覧のとおりsDef *、メソッドの戻り値を取得したポインターは、現在 を指してい0x2fe03804ます。これはメソッドが返すものではありません! これは、ヒープではなく、スタック上のどこかを指しているポインターだと思います。(std::vector クラスはそのオブジェクトをヒープに格納するため、ヒープである必要がありますよね?)。

Valgrind でサポートされていない Mac OS X 10.8 を使用しているため、まだ Valgrind を使用できません。

私はこの振る舞いに完全に驚いています。なぜこれが起こっているのかわかりません...コンパイラが壊れているのでしょうか、それとも奇妙な「最適化」を行っているのでしょうか?

前もって感謝します!
マルティン


DeadMG のコメントを明確にするには:

私はさまざまなテーマを使用しています:

iron
wood
ice

等...

私の識別子は次のようになります。

iron__downside_touch_and_go
iron__platform__700_65
iron__wall_bang
wood__platform__600_40

など...私がしたいのは、1つのテーマ内で特定のインデックスを持つ構造を選択することです。したがって、すべてのテーマの構造のセットを一緒に索引付けするのではなく、1 つのテーマのサブセットの索引を作成します。もう一度コードを見てください:)


アップデート!!!

間違った情報を流しました。ベクトルはタイプですstd::vector<StructureDef>!! オブジェクトを格納します。ポインタではありません!

したがって、私が呼び出しで行っていること (と思います).operator->()は、: と同じです&(*it)。そして、それは機能しているようです。私には、 & と * を続けて書くのは少しばかげているように見えました。


@ベン・フォークト:

建築: ここに画像の説明を入力

最適化: ここに画像の説明を入力

4

2 に答える 2

2

私が使用していたデバッガー (LLDB であり、最初は GDB ではありませんでした) がメモリ値を正しく表示していないように見えました。GDB に切り替えた後、デバッガーは私が見ることを除いてメモリ アドレスを示しました。次のような print ステートメントを追加すると、次のようになります。

printf("StructureDef* pointer = %llx\n", (unsigned long long int)(void*) sDef);

GDBが正しいようです。テスト目的で LLDB に戻したところ、魔法のように LLDB も正しく機能していました。

たぶん、私はこの男が書いたものを扱っています: https://stackoverflow.com/a/9709462/155137

LLDB デバッガーのバグだといいのですが。そうしないと、私のインストールで何かが本当に壊れていると思うからです。

于 2012-07-10T14:59:54.977 に答える
0

ベクトルを からstd::vector<StructureDef>に変更しstd::vector<StructureDef*>ます。ベクターに への構成ポインターを設定するときはStructureDef、ヒープ上の各ポインターに動的にメモリを割り当てます。

于 2012-07-10T15:07:57.490 に答える