【问题标题】:c Dynamic allocation of struct arrayc struct数组的动态分配
【发布时间】:2020-12-30 05:35:26
【问题描述】:

我有一个结构数组的动态分配分配。 我很难理解/解释为什么我需要指向指针的指针而不是像常规数组指针那样, 也许有人可以解释? 代码如下 我添加了包括主函数在内的整个代码。

struct Date {
    int year;
    int month;
    int day;
};

struct Student {
    char name[100];
    float grades;
    float points;
    int id;
    struct Date birth_date;
};

struct Student** get_student_data(int* number_of_student)
{
    printf("how many students in your class? ");
    scanf("%d", number_of_student);

    struct Student** student_pointers_array = malloc(sizeof(struct Student*) * *number_of_student);
    if (student_pointers_array == NULL)
        return;
    struct Student* student_array = malloc(sizeof(struct Student) * *number_of_student);
    if (student_array == NULL)
        return;
    for (int i = 0; i < *number_of_student; i++)
    {
        printf("Enter Name\n");scanf(" %[^\n]s", &student_array[i].name);
        printf("Enter Grades\n");scanf("%f", &student_array[i].grades);
        printf("Enter Points\n");scanf("%f", &student_array[i].points);
        printf("Enter ID\n");scanf("%d", &student_array[i].id);
        printf("Enter year\n");scanf("%d", &student_array[i].birth_date.year);
        printf("Enter month\n");scanf("%d", &student_array[i].birth_date.month);
        printf("Enter day\n");scanf("%d", &student_array[i].birth_date.day);
        student_pointers_array[i] = &student_array[i];
    }

    return student_pointers_array;
}
void print_student_data(struct Student** student_data, int number_of_student)
{
    for (int i = 0; i < number_of_student; i++)
    {
        printf("name: %s\n", student_data[i]->name);
        printf("average: %f\n", student_data[i]->grades);
        printf("academic points: %f\n", student_data[i]->points);
        printf("ID: %d\n", student_data[i]->id);
        printf("birth year: %d\n", student_data[i]->birth_date.year);
        printf("birth month: %d\n", student_data[i]->birth_date.month);
        printf("birth day: %d\n", student_data[i]->birth_date.day);
    }
}

void main()
{
    int number_of_student = 0;
    struct Student** student_data = get_student_data(&number_of_student);
if (student_data == NULL)
        return;
    print_student_data(student_data, number_of_student);
    free(student_data);
}

【问题讨论】:

  • 我们可以对任何 * 或 ** 做任何事情,这取决于我们需要将什么存储在哪里
  • 如果您返回 struct Student *,则根本不需要 student_pointers_array。您的编译器不应让您在定义为返回指针值的函数中编写return;。你应该使用return NULL:
  • 我添加了更详细的代码,我只是想了解解决方案及其背后的理论。
  • void main() 在 Windows 以外的任何地方都是错误的,即使在那里也不推荐(AFAIAC)。您的free(student_data) 泄漏内存——您也需要删除其他内存分配(我相信free(student_data[0]) 应该可以完成这项工作)。

标签: c pointers struct


【解决方案1】:

您不需要使用struct Student ** — 您可以使用单级指针,如下所示:

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

struct Date
{
    int year;
    int month;
    int day;
};

struct Student
{
    char name[100];
    float grades;
    float points;
    int id;
    struct Date birth_date;
};

static
struct Student *get_student_data(int *number_of_student)
{
    printf("how many students in your class? ");
    scanf("%d", number_of_student);

    struct Student *student_array = malloc(sizeof(struct Student) * *number_of_student);
    if (student_array == NULL)
        return NULL;
    for (int i = 0; i < *number_of_student; i++)
    {
        printf("Enter Name\n");
        scanf(" %[^\n]s", student_array[i].name);
        printf("Enter Grades\n");
        scanf("%f", &student_array[i].grades);
        printf("Enter Points\n");
        scanf("%f", &student_array[i].points);
        printf("Enter ID\n");
        scanf("%d", &student_array[i].id);
        printf("Enter year\n");
        scanf("%d", &student_array[i].birth_date.year);
        printf("Enter month\n");
        scanf("%d", &student_array[i].birth_date.month);
        printf("Enter day\n");
        scanf("%d", &student_array[i].birth_date.day);
    }

    return student_array;
}

static
void print_student_data(struct Student* student_data, int number_of_student)
{
    for (int i = 0; i < number_of_student; i++)
    {
        printf("name: %s\n", student_data[i].name);
        printf("average: %f\n", student_data[i].grades);
        printf("academic points: %f\n", student_data[i].points);
        printf("ID: %d\n", student_data[i].id);
        printf("birth year: %d\n", student_data[i].birth_date.year);
        printf("birth month: %d\n", student_data[i].birth_date.month);
        printf("birth day: %d\n", student_data[i].birth_date.day);
    }
}

int main(void)
{
    int number_of_student = 0;
    struct Student* student_data = get_student_data(&number_of_student);
    if (student_data != NULL)
    {
        print_student_data(student_data, number_of_student);
        free(student_data);
    }
    return 0;
}

这也简化了内存释放。问题中的代码泄漏了结构数组(它只释放了指针数组)。

【讨论】:

  • 谢谢,那么首先使用指针指向指针的原因是什么?使用'->'语法?或者在解决方案背后还有其他合理的立场吗?
  • 我看不出使用指针数组和结构数组的充分理由。如果每个结构都是单独分配的,那么你也需要一个指针数组,但是一次性分配所有结构,使用这两个数组没有好处,也有一些缺点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2016-09-29
  • 2014-08-19
  • 1970-01-01
相关资源
最近更新 更多