私はCの初心者ですが、ターミナルのgccを介してxcodeで次のコードを実行しています。
#include <stdio.h>
#include <string.h>
int main(){
char name[12] = "Roman Mirov";
printf("My name is %s\n", name);
name[8] = 'k';
printf("My name is %s\n", name);
char greeting[] = "hello";
printf("%s %s\n", greeting, name);
strcpy(greeting, "greetings, ");
printf("%s%s\n", greeting, name);
return 0;
}
そしてそれはこれを出力します:
My name is Roman Mirov
My name is Roman Mikov
hello Roman Mikov
Abort trap: 6
私の質問は、最後の行を出力「greetings、Roman Mikov」として表示する代わりに、なぜエラーが生成されるのかということです。
この場合、宛先greeting
には、sourceのコンテンツ全体を格納するのに十分なスペースがないため、範囲外です。 未定義の動作 を呼び出すアクセス。
詳述すると、配列greeting
のサイズは、提供された初期化子のサイズによって決定されます。
char greeting[] = "hello";
この場合、 "hello"
これにより、ヌルターミネータを含めてサイズが6になります。
さて、後であなたはもっと大きなstringをメモリに入れようとします、
strcpy(greeting, "greetings, ");
ここで、ソースのサイズは12バイトですが、宛先には6バイトしか含まれていません。これにより、境界オーバーランが発生し、結果にUBが発生します。クラッシュ(または中止)は、UBの考えられる副作用の1つです。
この場合、greeting
変数はサイズが6のchar
の配列です(hello
および_\0
_のため)。
したがって、strcpy(greeting, "greetings, ");
を使用して_"greetings, "
_をgreeting
にコピーすることはできません。 greeting
は_11+1
_文字の配列を含むのに十分ではないため
=>ここにエラー_abort trap : 6
_があります
この行では、5 +1文字の配列を割り当てています。
char greeting[] = "hello";
この行では、その配列に11 +1文字を書き込もうとしています。
strcpy(greeting, "greetings, ");