简体   繁体   English

如何在 C 中返回指向结构数组的指针

[英]How to return pointer to array of struct in C

I created a struct of student inside the function using malloc and populated it with data.我使用malloc在 function 中创建了一个student结构,并用数据填充了它。 I want to return the address of the array of struct back to main and print it line by line, but with my implementation, it is not printing.我想将结构数组的地址返回给main并逐行打印,但是在我的实现中,它没有打印。 I debugged my code and indeed, it is able to return the address of my array to main .我调试了我的代码,确实,它能够将我的数组的地址返回给main I don't know why it's not printing though.我不知道为什么它不打印。 Any thoughts?有什么想法吗?

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

typedef struct student Student;

struct student
{
    char name[100];
    int age;
    char sex;
};

Student **getstudents(int n)
{
    Student **t = malloc(sizeof *t * n); // memory for the array of pointers
    for (int i = 0; i < n; i++) // memory for each individual pointer
    {
        t[i] = malloc(sizeof **t);
    }
    /* Data is inputted by user with form <student> <sex> <age>, then get mapped to the struct *t */

    return t; /* Pointer to an array of pointers */
}


int main()
{
    Student **students;
    int n;
    scanf("%d\n", &n);
    students = getstudents(n);
    for (int i = 0; i < n; i++)
    {
        printf("Name: %s, Sex: %s, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
    }

    for (int i = 0; i < n; i++)
    {
        free(students[i]);
    }
    free(students);
    return 0;
}


I am only allowed to modify the code in `Student **getstudents(int n)`. 

In the line:在行中:

Student *t = (char*)malloc(sizeof(Student)*n); 

You are allocating memory for one pointer, if you want to return a pointer to pointer, you need to allocate memory accordingly:您正在为一个指针分配 memory ,如果要返回指向指针的指针,则需要相应地分配 memory :

Student **t = malloc(sizeof *t * n); // memory for the array of pointers

for(int i = 0; i < n; i++){ // memory for each individual pointer
    t[i] = malloc(sizeof **t);
}

To later free the pointers you also need to free each individual pointer previously allocated:要稍后释放指针,您还需要释放先前分配的每个单独的指针:

for(int i = 0; i < n; i++){ // memory for each individual pointer
    free(students[i]);
}
free(students);

Note that the specifier for a single character is %c , the printf will need to be corrected:请注意,单个字符的说明符是%c ,需要更正 printf :

printf("Name: %s, Sex: %c, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
//                     ^^

Another thing I would change is in strncpy instead of null terminating the string later I would let the function do it:我要更改的另一件事是在strncpy而不是 null 稍后终止字符串,我会让 function 这样做:

// one more byte and strncpy terminates the string for you
strncpy(t[i]->name, data[0], strlen(data[0]) + 1); 
//      ^^^^
// already corrected for the new pointer

Having corrected the issues here is a possible alternative you can use to parse all the elements in the struct with sscanf from entry in one go, if you want to:更正了此处的问题是一种可能的替代方法,您可以使用sscanf从一个 go 中的entry解析结构中的所有元素,如果您愿意:

Student **getstudents(int n)
{
    Student **t = malloc(sizeof *t * n); // memory for the array of pointers

    if (t == NULL)
    {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < n; i++) // memory for each individual pointer
    {
        t[i] = malloc(sizeof **t);
        if (t[i] == NULL)
        {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
    }

    for (int i = 0; i < n; i++)
    {
        char entry[100];
        if (fgets(entry, sizeof entry, stdin))
        {
            if (sscanf(entry, "%25s %c %d", t[i]->name, &t[i]->sex, &t[i]->age) != 3)
            {
                // deal with bad input
            }
        }
    }
    return t;
}

anastaciu answer points many troubles, but there is others: anastaciu 的回答指出了很多麻烦,但还有其他问题:

Another problem in your code is that you use '%s' for the sex as sex is a only char.您的代码中的另一个问题是您使用 '%s' 作为性别,因为性别是唯一的字符。 You should use %c or else the printf function will try to parse a string and will get a SEGFAULT.您应该使用 %c 否则 printf function 将尝试解析字符串并获得 SEGFAULT。

I urge you too to stricly check every memory allocation.我也敦促您严格检查每个 memory 分配。 Always.总是。

The revised code from my pov:我的pov修改后的代码:

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

typedef struct student Student;

struct student{
    char name[100];
    int age;
    char sex;
};

Student **getstudents(int);
void free_students(Student**, int);

int main(){
    Student **students;
    int n = 4;
    students = getstudents(n);
    for(int i = 0; i < n; i++){
        if (students[i] != NULL) {
             printf("Name: %s, Sex: %c, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
        }
    }
    free_students(students, n);
    return 0;
}

Student **getstudents(int n){
    Student **t = (Student **)malloc(sizeof(Student *)*n);
    if (t==NULL) {
       perror("Memory: can't allocate.");
       return(NULL);
    }

    /* Input: <name> <sex> <age> */
    char entry[100];
    for(int i = 0; i < n; i++){
        t[i]=NULL;
        if (fgets(entry,100,stdin) != NULL) {
            int readBytes = strlen(entry);
            char newString[3][25];

            int k,j,ctr;
            j=0; ctr=0;
            for(k=0;k<=readBytes;k++)
            {
                if(entry[k]==' '||entry[k]=='\0'||entry[k]=='\n')
                {
                    newString[ctr][j]='\0';
                    ctr++;
                    j=0;
                }
                else
                {
                    newString[ctr][j]=entry[k];
                    j++;
                }
            }

            t[i] = (Student *)malloc(sizeof(Student));
            if (t[i] == NULL) {
               perror("Memory: can't allocate.");
               return(NULL);
            }
            strncpy(t[i]->name, newString[0], strlen(newString[0]));
            t[i]->name[strlen(newString[0])] = '\0';
            t[i]->sex = *newString[1];
            t[i]->age = atoi(newString[2]);
       }
    }

    return t;
}

void free_students(Student **students, int n){
    for(int i=0; i<n; i++){
        free(students[i]);
    }
    free(students);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM