c - 为什么这个程序在我的电脑上运行正常,但在另一台电脑上却导致溢出?

标签 c pointers struct

我正在教一个 friend C。我们正在使用结构和指针,我给了他一个程序让他在他的电脑上试用。我们打算逐行解构程序,这样他就能理解结构和指针是如何协同工作的。在我这边,我得到了这个结果:

Value of a in astr is 5
Value of b in astr is 5.550000
Value of c in astr is 77
Value of d in astr is 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 struct 类型的对象。

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

或者,更简单、更稳健:

astr = malloc(sizeof *astr);

(sizeof 的参数未被评估,因此 sizeof *astr 为您提供了 astr 指向的大小,而无需尝试取消引用它。转换是不必要的,因为 malloc 返回一个 void*,它被隐式转换为所需的指针类型。)

其次,您使用的错误格式 不是打印astr->d 的正确格式。 %f 格式适用于 floatdouble 参数(因为 float 参数到 printf 被提升为 double)。 long double 参数的正确格式是 %Lf。只需将 %f 用于 astr->bastr->d。 (以 C99 "%lf" 开头等同于 %f,但最好只使用 %f'。)

第三(好吧,我算错了),你应该通过将结果与NULL 进行比较来检查malloc 调用是否成功。如此小的分配不太可能失败,但持续检查是一个很好的习惯。如果失败,您可以通过错误消息中止程序(对于较大的程序,可能需要一些更复杂的错误处理)。

关于c - 为什么这个程序在我的电脑上运行正常,但在另一台电脑上却导致溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37514469/

相关文章:

c - 使用未声明的标识符 'a'

c - ELF64/x86_64和内存映射段的起始地址(对于共享对象)

c - c 中的 short 和 int

c - 未在指针给定的地址处显示正确的值

c - 在C语言中,如何通过双指针访问数组中的元素

c++ - 为什么C++既有类又有结构?

c++ - 一个 Debug-Print 函数来控制它们

c - 如何从 2 个输入文件中按升序将整数排序到新文件中?

c - 使用 int 指针保存 int 类型数组的地址及其索引值误解

C - 从二进制文件读取到任何结构