位字段给出分段错误

时间:2016-09-25 20:30:07

标签: c segmentation-fault structure scanf bit-fields

这是C语言。当我运行以下程序时,无论我给出多小的值,我都会得到运行时分段错误。请帮我找出原因。

#include <stdio.h>
#include <stdlib.h>
struct date
{
unsigned day:
    5;
unsigned month:
    4;
unsigned year:
    12;
};
struct emp
{
    char name[10];
    struct date d;
};
int compare(const void * a, const void * b)
{
    struct emp *orderA = (struct emp *)a;
    struct emp *orderB = (struct emp *)b;
    return (  orderA->d.year - orderB->d.year  );
}
int main ()
{
    int i;
    struct emp e[5];
    for (i = 0;i < 5;i++)
    {
        scanf("%s %d %d %d", e[i].name, e[i].d.day, e[i].d.month, e[i].d.year);
    }
    qsort(e, 5, sizeof(struct emp), compare);
    for (i = 0;i < 5;i++)
    {
        printf("%s %d %d %d\n", e[i].name, e[i].d.day, e[i].d.month, e[i].d.year);
    }
    return 0;
}

1 个答案:

答案 0 :(得分:5)

当您希望scanf()扫描您的内容时,您必须传递 地址 的内容,而不是实际内容。 (如果您未将某些内容的地址传递给scanf(),那么scanf()如何在其中存储值?)

现在,在C引用e[i].name之类的数组时,实际上是指数组的第一个元素的地址,因此您不必对此做任何特殊处理。 (除了小心不要输入超过9个字符的名称,wh00ps,这是非常不安全的,小心!)

但是对于整数,例如e[i].d.day等,你不能按原样传递int,因为scanf()需要指针,所以它会处理你的int }作为指向int的指针,因此它将允许用户输入一个数字,然后它会尝试将数字存储在该指针指向的位置,这只是内存中的一些随机位置,并且因此是段错误。

因此,当您要扫描int时,您必须传递int的地址,如下所示:&e[i].d.day

除了当整数是记录的字段时,你不能取其地址,因为它没有自己的地址,它存在于存储在地址的某些位中。

所以,我担心你将不得不写一个特殊的函数来阅读你的struct date,你必须声明个别的int,将它们的地址传递给{{1然后将结果值存储在scanf()