在gets(指针)改变char指针的值之后,scanf中的格式说明符错误("%d",unsigned short int),但为什么呢?

cla*_*688 1 c int unsigned pointers short

我最近尝试了一些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);
}
Run Code Online (Sandbox Code Playgroud)

直到scanf一切都很好.读取的字符串被写入指向的内存空间指针.但是,在处理了scanf后,指针的值会发生变化,因此指针指向任何空间.所以不仅我的字符串丢失了,而且在尝试访问/释放不属于我的程序的内存时也会出现分段错误.

价值变化显然是随机的.每次我调试这个程序时,指针都会变为另一个值.

我已经推断出unsigned short int是错误的,或者说是我的scanf中错误的格式说明符(%d而不是%hu).如果我将unsigned short int更改为int或使用%hu作为说明符,一切正常.所以有解决方案.

但我仍然好奇为什么以及指针如何受到这个错误的影响.任何人都可以帮助我吗?

unw*_*ind 15

您的程序有未定义的行为.

你需要告诉scanf()它只有一个整数的空间,它怎么知道存储数字的大小呢?

改成:

scanf("%hu", &temp);
Run Code Online (Sandbox Code Playgroud)

其中h的意思是"一半",即short,并且uunsigned.您未能使用正确的格式转换说明符导致未定义的行为,其中scanf()覆盖了内存中的相邻变量.

此外,请注意gets()由于非常危险而被弃用:请不要使用它.使用更加乖巧的fgets()代替.并且从不扩展分配sizeof (char),这只是一种非常难以阅读的写作方式,* 1没有增加任何价值.