带有structs建议的C malloc()



我有两个结构,我有一个30指针的StudentType数组。我对malloc()有问题。当我编译它时,它是可以的。但当我尝试调试它时,在Dev c++中显示"Segmentation Fault"。

在Eclipse中,它在控制台上显示任何内容。我认为我的错误在于以下几行代码:

students[0]=(StudentType *)malloc(sizeof(StudentType)*NumOfStudents);
(*students[NumOfStudents]).firstName=(char*)malloc(sizeof(char[30]));
(*students[NumOfStudents]).lastName=(char*)malloc(sizeof(char[30]));

这是我代码的一部分。

#include <stdio.h>
#include <stdlib.h>
typedef struct{
    float firstAssignment;
    float secondAssignment;
    float midterm;
    float final;
    float finalMark;
}StudentRecordType;
typedef struct{
    char *firstName;
    char *lastName;
    int idNumber;
    StudentRecordType marks;
}StudentType;
StudentType *students[30];
char firstName[30];
char lastName[30];
int ReadFromFile();
int PrintAll();
int NumOfStudents;
int i;
int main(void)
{
    ReadFromFile();
}
int ReadFromFile()
{
    FILE *fp;
    fp=fopen("project2-askhsh2.dat","r");
    if(fp==NULL)
    {
        printf("Error opening file.n");
    }
    else
    {
        printf("Successful open of project2-askhsh2.datn");
    }
    fscanf(fp,"%d",&NumOfStudents);
    printf("%dn",NumOfStudents);
    students[0]=(StudentType *)malloc(sizeof(StudentType)*NumOfStudents);
    (*students[NumOfStudents]).firstName=(char*)malloc(sizeof(char[30]));
    (*students[NumOfStudents]).lastName=(char*)malloc(sizeof(char[30]));
    for(i=0;i<NumOfStudents;i++)
    {
        (*students[i]).idNumber=i;
        fscanf(fp,"%s %s", (*students[i]).firstName,(*students[i]).lastName);
        fscanf(fp,"%f %f %f %f",(*students[i]).marks.firstAssignment,(*students[i]).marks.secondAssignment,(*students[i]).marks.midterm,(*students[i]).marks.final);
        printf("%s",(*students[i]).firstName);//, students[i].lastName);
    }
}

(*students[NumOfStudents]).firstName=(char)malloc(sizeof(char[30]));

首先,演员阵容完全错误。投射到char会丢失信息
其次,在C中,不要强制转换malloc()的返回值。它充其量是多余的,并且可能会隐藏编译器在没有强制转换的情况下会捕捉到的错误。

如果要进行强制转换,请强制转换为char*

在使用students指针时,您似乎有一个额外级别的指针,不需要引起一些混乱。您还可以访问已分配的数组的末尾。

所以不是

StudentType *students[30];

这给了你一个30个指向StudentType的指针数组,我想你可能只是想要:

StudentType *students;

它只是一个指向StudentType的普通指针,可以用作动态分配数组的基础。然后当你进行分配时,你会这样做:

students = malloc(sizeof(*students) * NumOfStudents);

在使用这些StudentType之前,您必须初始化它们中的每一个。

for(i=0;i<NumOfStudents;i++)
{
    students[i].firstname = malloc(30);
    students[i].lastname = malloc(30);
}

请注意,现在每个StudentType都作为一个元素从students数组中直接访问为student[i],而不是错误的*students[i]。您可以将其扩展到代码的其余部分。请记住,您只能从索引0访问NumOfStudents-1,因此不要使用students[NumOfStudents]。

您将遇到的另一个问题是,当您使用fscanf()时,您需要传递变量的地址,以便使用"与"运算符将结果存储在中。目前您只传递值,例如,您应该使用&students[i].marks.firstAssignment而不是(*students[i]).marks.firstAssignment,假设您也修复了指针错误。

这两条语句是错误的:

(*students[NumOfStudents]).firstName=(char*)malloc(sizeof(char[30]));
(*students[NumOfStudents]).lastName=(char*)malloc(sizeof(char[30]));

C数组是零索引的,因此您试图取消引用一个超过数组大小的数组。假设您想要设置students[]的最后一个元素的名字和姓氏,那么您需要取消引用索引NumOfStudents - 1

您不需要将malloc()的结果强制转换为char *(假设您正在编写C应用程序)。

sizeof(char)是1,所以您只需要编写malloc(30)

(*students[NumOfStudents]).firstName=(char*)malloc(sizeof(char[30]));

我想你的意思是:

students[some_index]->firstName = malloc(30);

some_index的值低于NumOfStudents。

所以你的循环变成:

for(i=0; i < NumOfStudents ; i++)
    {
        /* students[] is an array of pointers
        ** students[i] is a pointer
        */
        students[ i ] = malloc(sizeof *students[ i ]);
        students[ i ]->idNumber=i;
        students[ i ]->firstName = malloc(30);
        students[ i ]->lastName= malloc(30);
        fscanf(fp,"%s %s"
            , students[i]->firstName
            , students[i]->lastName
            );
        fscanf(fp,"%f %f %f %f"
            , &students[i]->marks.firstAssignment
            , &students[i]->marks.secondAssignment
            , &students[i]->marks.midterm
            , &students[i]->marks.final
            );
        printf("%s",students[i]->firstName);//, students[i].lastName);
    }

使用名为"i"的全局索引可能被认为是糟糕的风格。

相关内容

  • 没有找到相关文章