1

呼び出された単純な再帰構造体Recursiveがあり、その const 配列をプログラムが必要とする値で初期化したいと考えています。次に、 と呼ばれる単純なイテレータ関数を使用IterateAuxし、main. 今までのコードを見てください:

#include <iostream>
#include <string>

struct Recursive
{
    std::string data;
    Recursive* Children;
};

void IterateAux(Recursive* Item)
{
    int i = -1;
    while (Item[++i].data != "")
    {
        std::cout << Item[i].data << "\n";
        if (Item[i].Children)
            IterateAux(Item[i].Children);
    }
}

int main()
{
    IterateAux( (Recursive*)Parent );
    return 0;
}

次のような const 配列がある場合は、次のように機能します。

const Recursive Children[] =  {
    {"Child1", NULL},
    {"Child2", NULL},
    {"", NULL}
};

const Recursive Parent[] = {
    {"Parent1", NULL},
    {"Parent2", NULL},
    {"Parent3", Children },
    {"", NULL}
};

しかし、次のネストされたフォームはそうではありません:

const Recursive Parent[] = {
    {"Parent1", NULL},
    {"Parent2", NULL},

    {"Parent3", (Recursive[])
        {
            {"Child1",NULL},
            {"Child2",NULL},
            {"", NULL}
        }
    },
    {"", NULL}
};

そして、問題はなぜですか?どうすればこれを機能させることができますか?

私の調査では、最初はポインターが無効である可能性があると考えていましたが、代わりにデータで.children試してみると、問題なく機能しました。intstd::string

データを使用std::stringすると、GDB がメッセージとともにクラッシュするDuring startup program exited with code 0xc0000135.ため、プログラムをデバッグすることさえできません! 配列の初期化コードがどこかで混乱しているのかもしれません...

これらすべてをGCC 4.6で試しました。

4

1 に答える 1

0

ちょっとした作業で、それを gdb に表示させることができます。IterateAux の while ステートメントにブレークポイントを設定します。それは親をうまく通過し、次にtが子供のケースに到達すると、作業ケースでこれが表示されます。

(gdb) p Item[0]
$2 = {data = "Child1", Children = 0x0}

そしてこれは失敗した場合です:

(gdb) p Item[0]
$2 = {data = <error reading variable: Cannot access memory at address 0xfffffff4>,
Children = 0x48d24d79}

したがって、Recursive[] へのキャストは、最初のケースと同じ形式にコンパイルされていないという事実を隠しているようです。

-Wall を指定して g++ 4.6.3 でコンパイルしていますが、警告は表示されません。

于 2012-05-19T14:19:42.770 に答える