0

これをできるだけ速く簡潔にするために、これは私のコードです:

    char* aiMove = getAIMove();
    cout << aiMove;
    cout << "\n" << numMoves << ": " << aiMove << "\n\n";
    return aiMove;

そしてこれは私の出力です:

    a0 a1
    0: �����������������������7

したがって、最初の行はgetAIMove()を呼び出し、戻り値(char *)をaiMoveに割り当てます。

2行目はaiMove(a0 a1)を出力します。

3行目は、numMovesとaiMoveをcoutに取り込んで出力しますが、代わりに奇妙な値を出力しています。

4行目はaiMoveを返します。これは、印刷された奇妙な値であると私が調べたものです。

aiMoveの値が変更されたのはなぜですか?これは、整数値をcout(この場合はnumMoves)に渡した場合にのみ発生するようです。

助けてください!ありがとう、パトリック:)

編集:私が言及するのを忘れたもう1つのことは、この奇妙な動作は、このコードブロックが初めて実行されたときにのみ発生し、プログラム中に実行されるたびに正常に出力されることです。

4

2 に答える 2

3

getAIMoveこれは、システムが自由に再利用できると感じたメモリへのポインタを返したことを明確に示しています。スタックまたはヒープからの後続の割り当てにより、返されたポインターが上書きされました。

これには多くの方法がありますが、これがおそらく最も一般的です。

char *GetAIMove()
{
    char buf[128];
    strcpy(buf, "a0");
    strcat(buf, " ");
    strcat(buf, "a1");
    return buf; // oops, buf won't exist after we return
}

おっとっと。このコードは、返されるとすぐに存在しなくなるバッファへのポインタを返します。この問題の典型的な修正はreturn strdup(buf);. 関数の呼び出し元は、処理が終了したときに文字列を解放する必要があることを覚えておいてください。

別の方法は次のとおりです。

std::string GetAIMove()
{
 // ...
 return foo;
}

char* aiMov e= GetAIMove();
// aiMove points to the contents of the returned string, no longer in scope.

これに対する修正はstd::string aiMove = GetAIMove. aiMove文字列をスコープ内に保持するようになりました。

しかし、最善の解決策は、文字列を最後まで保持するように特別に設計された文字列クラスを使用することです。

std::string GetAIMove()
{
    std::string foo;
    foo = "a1";
    foo += " ";
    foo += "a2";
    return foo;
}

std::string aiMove = GetAIMove();

このコードには多くのコピーが含まれているように見えますが、実際には、最新のコンパイラを使用すると効率的になります。ですから、コードを単純で論理的で、理解しやすく維持しやすいものにしておくことを悪く思わないでください。

于 2012-04-19T07:57:50.683 に答える
0

いいえ、coutパラメータの内容は変更しません。

おそらく、事前に何か間違ったことをしていて、未定義の動作に陥っています。

于 2012-04-19T07:57:26.487 に答える