我在教一个朋友C。我们正在研究结构和指针,我给了他一个程序,让他在电脑上试用。我们将逐行解构程序,这样他就能理解结构和指针是如何协同工作的。最后,我得到了这样的结果:
a在astr中的值是5
astr中b值为550000
astr中c值为77
astr中d值为888.888800
在他的计算机上,除了最后一个astr->d的值打印出一些非常大的负数外,程序大部分都在工作。所以我的问题是,为什么这件事发生在他的电脑上,而在我的电脑上却很好?下面是违规代码:

#include <stdio.h>
#include <stdlib.h>

int main(){
    struct a_struct{
        int a;
        float b;
        int c;
        double d;
    };

    struct a_struct* astr;

    astr = (struct a_struct*)malloc(sizeof(astr));

    astr->a = 5;
    astr->b = 5.55;
    astr->c = 77;
    astr->d = 888.8888;

    printf("Value of a in astr is %d\n", astr->a);
    printf("Value of b in astr is %f\n", astr->b);
    printf("Value of c in astr is %d\n", astr->c);
    printf("Value of d in astr is %lf\n", astr->d);

    return 0;
}

最佳答案

你至少有两个问题。
首先,您的malloc呼叫不正确。

astr = (struct a_struct*)malloc(sizeof(astr));

astr是指针,因此sizeof(astr)是指针的大小。您需要分配足够的内存来保存struct astruct类型的对象。
astr = (struct a_struct*)malloc(sizeof (struct a_struct)));

或者,更简单、更有力地说:
astr = malloc(sizeof *astr);

(不计算sizeof的参数,因此sizeof *astr提供astr指向的内容的大小,而不试图取消对它的引用。转换是不必要的,因为malloc返回一个void*,它被隐式转换为所需的指针类型。)
其次,您使用了错误的格式,而不是正确的格式来打印astr->d%f格式对floatdouble参数都有效(因为floatprintf参数升级为double)。long double参数的正确格式是%Lf。只需对%fastr->b使用astr->d。(从C99"%lf"开始相当于%f,但最好只是使用%f'
第三(好,我算错了),您应该通过将结果与malloc进行比较来检查NULL调用是否成功。如此小的分配不太可能失败,但坚持检查是一个很好的习惯。如果失败了,您可以用错误消息中止程序(对于较大的程序,可能需要更复杂的错误处理)。

08-19 12:40