2012-04-19 5 views
0

は、このように迅速かつできるだけ簡潔にするには、これは私のコードです:char配列の内容を変更することはできますか?

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

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

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

だから、最初の行はgetAIMoveを()呼び出しと戻りを割り当てvalue(char *)をaiMoveに設定します。

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

3行目はnumMovesとaiMoveをcoutに取り出して印刷しますが、代わりに奇妙な値が表示されます。

第4行目はaiMoveを返します。これは異常な値が出力されたことを検査しました。

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

助けてください! おかげで、 パトリック:)

編集:私は言及を忘れてしまった別のものは、それが印刷し、プログラム中に実行されますすべての次の時間、このコードブロックを最初に実行されますと、この奇妙な行動が唯一起こるということです良い。

+4

getAIMove()はchar * getAIMove(){char str [] = "Patrick"です。 return str; } ???もしそうなら、ローカル変数へのポインタを返すのは間違いです。 – Jagannath

+5

あなたはgetAIMove()のコードを提供できますか?割り当てられたローカルスタックを返しますか? –

+0

@ Jagannathあなたが正しいです、getAIMove()は最終的にchar str []を返します。ありがとう:)私はまだcoutに整数値を渡すことで違いが生じるのは分かりませんが、S –

答えて

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(); 

注意を、現代のコンパイラますそれを効率化する。コードを単純で、論理的で、理解しやすく、維持しておくことが悪いと感じないでください。

+0

深い説明をありがとう! :) getAIMove()がstd :: stringを返すようにしてから、これを行うようにしても問題ありません:char * aiMove = getAIMove()。c_str(); ? –

+0

いいえ。文字列で呼び出される非constメソッドはすべて、返されたポインタを無効にし、デストラクタは非constです。だから再び 'aiMove'はもはや存在しないものの内容を指し示します。 [c_str](http://www.cplusplus.com/reference/string/string/c_str/)から返されるポインタは、文字列を変更できる操作が実行されるまで有効です。それを破壊するのは間違いない! –

0

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

あなたはおそらくあらかじめ間違ったことをしており、未定義の動作に陥っている可能性があります。

関連する問題