【问题标题】:Problem with pointer in array of structs in CC中结构数组中的指针问题
【发布时间】:2021-12-30 23:09:05
【问题描述】:

一个问题导致程序无法正常工作。我猜这与在结构数组中使用指针有关。尽管尝试了很多方法,但仍然没有发现:

#include <stdio.h>

typedef struct {
    char* courseName;
    char* courseDate;
    double grade;
}EXAM;

int main() {

    double averageGrade = 0;
    EXAM *exams[5];

    for(int i = 0; i < 5; i++){
        printf("Please enter course name:\n");
        scanf("%s", exams[i]->courseName);

        printf("Please enter course date:\n");
        scanf("%s", exams[i]->courseDate);

        printf("Please enter course grade:\n");
        scanf("%lf", &exams[i]->grade);

        averageGrade += exams[i]->grade;
    }

    averageGrade /= 5;
    printf("Your average grade is: %.1lf.", averageGrade);

    return 0;
}

【问题讨论】:

  • EXAM *exams[5] 定义了一个由 5 个指针组成的数组。该数组未初始化,因此exams[0]exams[1] 等在分配之前都是无意义的值。尝试将数据读入exams[0]-&gt;courseName 是错误的,因为exams[0] 不包含您可以写入的位置的地址。

标签: c pointers struct


【解决方案1】:

EXAM[*] 指向未分配的内存:

要创建一个包含 5 个考试对象的数组,请执行以下操作:

EXAM exams[5]; // Note there is no * character.

如果由于某种原因需要指针,那么您将需要为这些对象分配空间:

EXAM *exams[5];
for (int i=0; i<5; i++) {
  exams[i] = calloc(1, sizeof(EXAM));
}

你还需要为字符串分配空间:

在 C 中,当您在 %s 上使用 scanf 时,该字符串的空间必须已经分配。

所以你应该使用char courseName[256];,在堆上为字符串分配足够的空间,或者使用像getline()这样的函数来为你分配空间。

【讨论】:

    【解决方案2】:

    1:

    typedef struct {
        char* courseName;
        char* courseDate;
        double grade;
    }EXAM;
    

    将 courseName 和 courseDate 定义为 'char *' 意味着它们只是指针。没有任何分配的指针指向 NULL 或更可能指向垃圾。如何解决?
    使用静态分配的 char 数组定义您的结构,例如:

    typedef struct {
        char courseName[41];
        char courseDate[41];
        double grade;
    }EXAM;
    

    在签署任何内容之前动态分配它们:

    for (int i = 0; i < 5; i++) {
        exams[i]->courseName = (char *) calloc(41, sizeof(char));
        exams[i]->courseDate = (char *) calloc(41, sizeof(char));
    }
    

    在这两种情况下,您都应该确保该用户不会溢出此字段,因此我建议在 scanfs 中使用“%40[^\n]”而不是“%s”,这只是 Get up从用户到 40 个字符,直到您找到一个 '\n' 字符(用户按回车键)
    此外,在第一种情况下,您应该确保两个字符串都是以 null 结尾的字符串,一个简单的方法是在所有表中设置零。

    memset(exams, 0, sizeof(EXAM)*5);
    

    2:

    EXAM *exams[5];
    

    这也只是指针。那个未分配的指向 NULL 或垃圾。选择其中一个:

    EXAM exams[5];
    

    并使用“。”而不是'->'。
    或分配它们:

    for (int i = 0; i < 5; i++) {
        exams[i]= (EXAM *) calloc(1, sizeof(EXAM));
    }
    

    【讨论】:

      猜你喜欢
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多