我的分段错误的原因是什么?

时间:2010-09-22 05:15:35

标签: c arrays segmentation-fault structure

我正在尝试编写一个程序,使用输入重定向将文件中的条目读入动态分配的结构数组中。我的程序编译得很好但是我遇到了分段错误而且我找不到原因。

这是我的计划:

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

typedef struct StudentData
{
char* name;
char* major;
double gpa;
} Student;

int main()
{
Student* data = (Student*)malloc(sizeof(Student)*5);

int i;
for(i = 0; i < 5; i++)
{
 // allocate memory for name and read input
 data[i].name = malloc(50);
 *(data+i)->name == scanf("%s", (char*)&data[i].name);

 // allocate memory for major and read input
 data[i].major = malloc(30);
 *(data+i)->major == scanf("%s", (char*)&data[i].major);

 // read input for gpa
 (data+i)->gpa == scanf("%lf", &data[i].gpa); 

 //print array
 printf("%s\n%s\n%f\n", data[i].name, data[i].major, data[i].gpa);
 }
}  

任何线索?如果它看起来很明显,那是因为我对C来说比较新!

4 个答案:

答案 0 :(得分:6)

这一行:

*(data+i)->name == scanf("%s", (char*)&data[i].name);

暂时忽略奇怪和无效==&data[i].name是错误的,因为你正在获取指针的地址。此处data[i].name就足够了,因为name字段已经是scanf可以写入的地址。

(char*)的演员阵容可能关闭编译器 - 你为此目的输了吗:-)?由于&data[i].name的类型为char**scanf不接受,因此除非您强行将其投放到char*

作为一般性建议,请尽量避免使用scanf - 它会导致非常不安全的代码(正如您刚才看到的那样!)而是使用fgets来读取一行(来自标准输入) )然后将这条线分解为其成分。这最初可能需要更多的代码来实现,但会带来更安全,更可预测的代码。

答案 1 :(得分:2)

*(data+i)->name == scanf("%s", (char*)&data[i].name);

您在比较scanf的返回值是什么?只需删除第一部分。此外,data[i].name已经是指针,因此您不应再次使用该地址。它应该只是:

scanf("%s", data[i].name);  // no & because name is already a pointer

同样地:

scanf("%s", data[i].major);
scanf("%lf", &data[i].gpa);  // & here because gpa is just a double

答案 2 :(得分:1)

scanf使用了一些不必要的代码,例如*(data+i)->name ==。这没有任何用处(并且可能导致段错误)。如果它没有导致访问错误,它会将scanf的返回值与指针进行比较,然后忽略比较结果。 (一个像样的编译器会对此发出警告。)

在删除多余的代码之后,它在技术上是可以的,除了没有什么可以阻止缓冲区溢出。这可以通过控制输入数据或增加字符串长度的限制来完成,例如使用scanf("%50s", data[i].name);

答案 3 :(得分:0)

&data[i].name&data[i].major属于char **类型,因此您无法安全地将其投放到char *

丢失&符将纠正您的错误。

使用scanf()还存在其他逻辑错误,但这可能是压倒性的 - 如果您输入超过50个字符的名称后重新访问此代码,那就太好了。