-1

重複の可能性:
構造体で scanf を使用しようとするとセグメンテーション違反が発生する

私はCプログラミングが初めてで、次のコードがあります。

char *s;
scanf("%s",s);
printf("This is s %s",s);

上記のコード行により、セグメンテーション違反が発生しています。理由を教えてください。概念をより深く理解するためにこれを読むことができる記事はありますか?

4

4 に答える 4

2

その特定のエンティティ が所有するメモリ アドレスに書き込むことができます。

例:

char s[10];

10コンパイラは、文字を格納するために必要な十分なメモリを確保しs、自由に書き込むことができます。

あなたが言う時:

char *s;

ポインターsは、所有または予約されていないランダムなメモリアドレスを指しているだけです。そのメモリ アドレスに書き込むと、他のエンティティが所有するメモリに書き込むことになります。技術的には、これはUndefined Behaviorです。
実際には、書き込まれているメモリアドレスが他のエンティティによって所有されているかどうかに応じて、セグメンテーション違反が発生する場合と発生しない場合があります。ですから、あなたの注意を引くクラッシュに遭遇することは幸運です。とにかく、これは未定義の動作であるため、常に回避する必要があります。

スタックまたはヒープ上のメモリであっても、ポインタにメモリを割り当てる必要があります。

于 2012-10-01T06:12:40.633 に答える
1

fgets を使用して、配列とポインターでこれを試してください。

static void get_input()
{
    /* Array of 32 btyes long - no input can be 32 characters in total */
#define CHAR_SIZE 32
    char str_array[CHAR_SIZE];
    char *str_ptr = calloc(sizeof(char), CHAR_SIZE);

    /* Get input from user - limit the input to 32 bytes using fgets which is safer */
    printf("Please enter something: ");
    /* Clear the memory before using it */
    memset(str_array, 0, CHAR_SIZE);
    fgets(str_array, CHAR_SIZE, stdin);
    printf("The input was [ %s ]\n", str_array);

    /* Doing the same thing with a pointer */
    printf("Please enter something again: ");
    fgets(str_ptr, CHAR_SIZE, stdin);
    printf("The input again was [ %s ]\n", str_ptr);

    /* free memory */
    free(str_ptr);
}

それが役に立てば幸い、

于 2012-10-01T06:50:08.780 に答える
0

ポインタはアドレスを格納します。そのアドレスは常に予約済みメモリのアドレスでなければなりません。

ということでお譲り致しchar *sます。mallocまたはを使用して、メモリを予約/割り当てる必要がありますcalloc

char *s=malloc(10*sizeof(char));

これにより、char のサイズが 1 バイトであると仮定して、10 バイトのメモリが割り当てられます。free目的が完了した後、 free 関数を使用して割り当てられたメモリが必要であることを忘れないでください。

于 2012-10-01T06:18:51.780 に答える
0

ポインタを作成しましたが、現在は初期化されていません (アクセス権限のない場所を指している可能性があります)。

char *s;

配列として宣言するか

char s[20]; //this number should be big enough to hold the input

または、いくつかのメモリを割り当ててから、それをポイントします。

char *s = (char *) malloc (20*sizeof(char));

参照: scanf

于 2012-10-01T06:34:35.060 に答える