面接で以下の質問がありました。誰か説明してくれませんか?
void question( char *s, char *t)
{
while (*s++ = *t++);
}
面接で以下の質問がありました。誰か説明してくれませんか?
void question( char *s, char *t)
{
while (*s++ = *t++);
}
プログラムに重大なセキュリティ上の脆弱性をもたらします。どのような状況でも、このようなコードを書いたり、使用したりしないでください。
コードを分解すると、次のようになります。
*t++
が指す文字を読み取り、t
インクリメントしますt
。式の値は読み取られた文字です。*s++ = expression
s
その文字を whereポイントに書き込み、インクリメントしますs
。式の値は、書き込まれた文字です。while (expression);
式の値がゼロでない限りループし続けます。この場合、値ゼロの文字を書き込むまで。したがって、この関数は、ゼロ値の文字に到達するまでt
文字をコピーし続けます。これらを保持するのに十分な大きさの配列を指しているs
かどうかを判断する方法がないため、一般に、配列の末尾を超えて書き込み、未定義の動作を引き起こします。s
不要な影響のない微妙な動作から、クラッシュ、悪意のあるコードの実行まで、あらゆるものに影響を与えます。
この関数は、コピーされる文字数 (上限) が事前にわかっている場合にのみ呼び出すことができます。それがわかっている場合は、(通常) それぞれの値をチェックするよりも効率的にデータをコピーする方法があります。strcpy
したがって、この関数またはそれが近似する C ライブラリ関数 ( ) は (ほとんど) 使用しないでください。
文字列を終了するためにゼロ値文字を使用することは、C では一般的なイディオムです。C++ では通常、std::string
代わりにクラスを使用して文字列を表す方が便利です。その場合、同等のコードは単にs = t
であり、文字列のメモリを安全に管理します。
t
文字列をコピーし、。が指すメモリへのポインタをコピーしますs
。
operator=
割り当てられた値を返します。t
は、終了したNULL
文字列を指すことになっておりs
、その文字列を格納するのに十分な大きさのメモリを指す必要があります。
したがって、 。が指す文字列の終わりであるヒットが発生すると、while
ループは停止します。このループ中に、のすべての文字(とは異なる)がにコピーされます。\0
t
while
\0
t
s
少し拡張すると、次と同じになります。
while( *t != '\0' ) // while the current char is not NULL
{
*s = *t; // copy it into s
++s; // increment s, to point to the next byte
++t; // increment t, to point to the next char, that will be copied
}
*s = *t; // copy the last char of t - the '\0'
nullで終了する文字列t
をにコピーしますs
。としての意味論strcpy
。