2

私は最近、いくつかの C プログラミングを試みましたが、次の問題に出くわしました。MinGW 32 ビットで NetBeans 7.4 64 IDE を使用しています。これは私の問題を強調する短いコード例です:

int main(void) {

    unsigned short int temp;
    char *pointer;
    pointer = malloc(12 * sizeof(char));

    printf("The pointers value is %d \n", (int)pointer);
    printf("Type a short string:\n");

    gets(pointer);

    printf("The pointers value is %d \n", (int)pointer);
    printf("Type an int: \n");

//This line changes the char pointer to an apparently random value
    scanf("%d", &temp);

//Segmentation fault upon this point
    printf("The pointers value is %d \n", (int)pointer);

//And here as well
    free(pointer);


    return (EXIT_SUCCESS);
}

scanf まではすべて問題ありません。gets によって読み取られた文字列は、ポインタが指しているメモリ空間に書き込まれます。しかし、scanf が処理された後、ポインターの値が変更され、ポインターが任意のスペースを指すようになります。したがって、文字列が失われるだけでなく、プログラムに属していないメモリにアクセス/解放しようとすると、セグメンテーション違反も発生します。

値の変化は明らかにランダムです。このプログラムをデバッグするたびに、ポインターが別の値に変更されます。

unsigned short int に問題があるか、scanf のフォーマット指定子 (%hu ではなく %d) が間違っていると既に推測しています。unsigned short int を int に変更するか、指定子として %hu を使用すると、すべて正常に動作します。そこで解決策です。

しかし、この間違いによってポインタが影響を受ける理由と方法については、まだ興味があります。誰でも私を助けることができますか?

4

2 に答える 2

18

あなたのプログラムには未定義の動作があります。

短いscanf()整数のためのスペースしかないことを伝える必要があります。数値を格納するサイズを他にどのように知るのでしょうか?

への変更:

scanf("%hu", &temp);

wherehは「半分」、つまり を意味shortし、uは ですunsigned。適切なフォーマット変換指定子を使用しなかったため、未定義の動作が発生scanf()し、メモリ内の隣接する変数が上書きされました。

また、gets()は非常に危険なため非推奨です: 使用しないでください。fgets()代わりに、より行儀の良いものを使用してください。そして、 によって割り当てをスケーリングしないでください。これはsizeof (char)、非常に読みにくい書き方* 1であり、価値を追加しません。

于 2013-11-06T10:27:29.263 に答える
3

C では、特定の変数のメモリを超えて書き込むことを妨げるものは何もないからです。すべては単なるアドレスであり、このアドレスの後に何バイト書き込むことができるかはあなた次第であり、コンパイラーがチェックするものではありません。

short int は、通常の int よりも少ないバイト数のメモリを使用します。short int を割り当てました。次に、scanf に通常の int を書き込むように依頼しました。scanf は、割り当てられたメモリを超えて書き込み、たまたま short int の直後に配置された char *pointer の一部を上書きしました。これは、何が上書きされるかわからないため、未定義の動作と呼ばれます。ポインターが temp の直後にメモリ内にあるという事実は偶然です。

ポインタが無効なメモリ アドレスを指すようになり、アクセスしようとするとセグメンテーション フォールトが発生します。

ポインタは、実際には、メモリ アドレスを格納するもう 1 つの整数変数 (long) です。

于 2013-11-06T11:18:28.867 に答える