malloc()
NULL の機能と役割について少し混乱しているようです。
このmalloc()
関数はスペースを割り当てますが、スペースを値に初期化しません。からの戻り値malloc()
は、そのスペース (の最初のバイト) へのポインターです。ゼロ バイトを割り当てようとしない限り1malloc()
、要求した量のスペースを割り当てることができなかった場合にのみ、 からの戻り値はNULL になります2。
したがって、システムのメモリが極端に不足しない限り、プログラムは「Hello World」を出力しません。ポインタstring
は有効なメモリ位置になります。
完全に定義されていないのは、string
指し示すデータです。たとえば、次のように初期化する必要があります。
strcpy(string, "Hello World");
これで安全に実行できます:
printf("%s!\n", string);
初期化する前に、メモリを読み取るのは「安全」ではありません。あなたがその中に何を見つけるかについての保証はありません。プログラムがクラッシュすることはありませんが、表示される内容が得られます。
次のものも安全に使用できます。
if (fgets(string, 500, stdin) != 0)
printf("Read: %s", string);
fgets()
端末用のスペースが予約されていることに注意してください'\0'
。スペースを 1 つずつ縮小する必要はありません。
あなたが尋ねる:
またはまたは...string
のようなものによって変更されたかどうかを確認するにはどうすればよいですかstrcpy()
strcat()
ほとんどの実用的な目的では、メモリの内容が定義されていないため、変更されているかどうかを判断できません。本当に知りたい場合は、おそらく次のようにすることができます。
char *string_copy = malloc(500);
if (string_copy != NULL)
memmove(string_copy, string, 500);
割り当てられたメモリの元の内容のコピーを作成し、次を使用します。
if (memcmp(string_copy, string, 500) != 0)
...someone changed either string or string_copy (or both)...
かなり薄い氷です。割り当てられたスペースの値は定義されていませんが、実際には、それが機能しないことに驚いています。一方で、この知識に興味を持つような状況が思い浮かびません。メモリを割り当てる場合は、それを使用するためです — 通常はほとんどすぐに。
1 0 バイトを割り当てると、2 つの実装定義の動作のいずれかが得られます。NULL ポインターが返されるか、他のメモリ割り当てとは異なるアクセス可能なメモリのゼロバイト (安全にアクセスできない) への有効な非 NULL ポインターを取得します。どちらの方法でも、結果は に安全に渡すことができますfree()
。0 バイトを割り当てた場合、返されたポインタを介してメモリにアクセスしようとすると、未定義の動作が発生します。
2 Linux では、大量のメモリをmalloc()
要求することができ、それを割り当てたと主張する可能性があることに注意してください。