带有结构建议的C malloc()

时间:2012-02-04 12:53:39

标签: c pointers struct 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.dat\n");
    }
    fscanf(fp,"%d",&NumOfStudents);
    printf("%d\n",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);
    }

}

4 个答案:

答案 0 :(得分:3)

  

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

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

无论如何你要投,转向char*

答案 1 :(得分:2)

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

所以而不是

StudentType *students[30];

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

StudentType *students;

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

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

在使用之前,您必须初始化每个StudentTypes。

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

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

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

答案 2 :(得分:1)

这两个陈述是错误的:

(*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)

答案 3 :(得分:0)

(*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”的全局索引可被视为不良风格。