0

char *ポインタをに設定した後malloc(size)、それがまだ変更されていないかどうかを確認する方法はありますか?NULL割り当てられていないスペースへのポインタは評価されますが、明らかにそうではないと思いました。

char *string = malloc(500);
if(string==NULL) puts("Hello World");
else puts("It's not null");

これは出力するはずだと思います"Hello World"が、出力しません。strcpy()文字列がまたはstrcat()、または、さらに関連性の高い自分のプロジェクトによって変更されたかどうかを確認するには、次の方法があります。

fgets(string, 499, fr)
4

5 に答える 5

4

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()要求することができ、それを割り当てたと主張する可能性があることに注意してください。

于 2012-10-31T18:57:26.773 に答える
1

信頼できるクロスプラットフォームの方法ではできません。malloc()によって返されるメモリをすべてゼロに初期化しないのはなぜですか? その後、変更されたかどうかを確認できます。

あなたの例では、割り当てられたメモリを指すポインター自体の値をテストしています。失敗しない限り、null にすることはできませんmalloc()

于 2012-10-31T18:52:39.550 に答える
1

After setting a char * pointer to malloc(size), is there a way to check if it's still not been changed?

  • はい、あなたがやっていることはほとんど同じですが、ポインターを から開始する必要がありますNULL。次に、コードで変更されたかどうかがわかりNULLます。

I thought that a pointer to unassigned space would evaluate to NULL

いいえ、ポインターをNULLに設定すると、ポインターは次のように評価されますNULL

char *string = NULL;
if(string==NULL) puts("Hello World"); //Will execute this
else puts("It's not null");

string = malloc(500);  //Assuming this was successful

if(string==NULL) puts("Hello World");
else puts("It's not null");  //Now we'll execute this

I think this should output "Hello World" but it doesn't

  • NULLそうです、それは有効なポインター値ではないためです (malloc()成功したと仮定して)

How can I check if string has been changed by something like strcpy() or strcat() or fgets()

  • ポインター値からこれを確認することはできません。文字列がいつ変更されたかを追跡する必要があります。fgets()は失敗した場合に戻るNULLため、それが発生した場合、文字列は変更されませんでした。
于 2012-10-31T19:10:07.287 に答える
0

ポインタを整数変数と考えてください。その値はメモリアドレスです。したがって、ポインタがnullの場合、これは変数の実際の値が存在しないアドレスnull(値0で示される)であることを意味します。

char *p = (char *)malloc(100);あなたが求めているようなものを書くときは、コンパイラが100バイトの未使用のスペースを見つけて、そのスペースの最初のバイトのアドレスにpの値を設定することです。これで、変数に値があり、Nullではありません。

これに照らして、変数p自体は、このアドレス( C用語で)の後のメモリスロットが変更されるかどうかとは関係ありません。p*

于 2012-10-31T19:00:40.377 に答える
0

誰がこれを言ったのI thought that a pointer to unassigned space would evaluate to NULL but apparently notですか?

char *string = malloc(500);

stringその割り当てられたスペースの最初のバイトを指している、またはheap(割り当てが何らかの理由で失敗しない限り)したがって、stringポインターは ではありませんNULL

于 2012-10-31T18:56:20.357 に答える