如何return指向C中结构数组的指针
How to return pointer to array of struct in C
我使用 malloc
在函数内部创建了一个 student
的结构,并用数据填充了它。我想 return 将结构数组的地址返回到 main
并逐行打印它,但是在我的实现中,它没有打印。我调试了我的代码,确实,它能够 return 我的数组地址到 main
。我不知道为什么它不打印。有什么想法吗?
#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)`.
行中:
Student *t = (char*)malloc(sizeof(Student)*n);
你正在为一个指针分配内存,如果你想return一个指针指向指针,你需要相应地分配内存:
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);
}
要稍后释放指针,您还需要释放之前分配的每个指针:
for(int i = 0; i < n; i++){ // memory for each individual pointer
free(students[i]);
}
free(students);
注意单个字符的说明符是%c
,printf需要更正:
printf("Name: %s, Sex: %c, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
// ^^
我要更改的另一件事是在 strncpy
中,而不是稍后用 null 终止字符串,我会让函数执行它:
// 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
已更正此处的问题是一种可能的替代方法,您可以使用它从 entry
一次性解析结构中的所有元素 sscanf
,如果您想要:
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;
}
麻烦点很多,还有其他的:
您代码中的另一个问题是您使用“%s”作为性别,因为性别是唯一的字符。您应该使用 %c,否则 printf 函数将尝试解析字符串并获得 SEGFAULT。
我也劝你严格检查每一个内存分配。总是。
根据我的 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]=='[=10=]'||entry[k]=='\n')
{
newString[ctr][j]='[=10=]';
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])] = '[=10=]';
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);
}
我使用 malloc
在函数内部创建了一个 student
的结构,并用数据填充了它。我想 return 将结构数组的地址返回到 main
并逐行打印它,但是在我的实现中,它没有打印。我调试了我的代码,确实,它能够 return 我的数组地址到 main
。我不知道为什么它不打印。有什么想法吗?
#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)`.
行中:
Student *t = (char*)malloc(sizeof(Student)*n);
你正在为一个指针分配内存,如果你想return一个指针指向指针,你需要相应地分配内存:
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);
}
要稍后释放指针,您还需要释放之前分配的每个指针:
for(int i = 0; i < n; i++){ // memory for each individual pointer
free(students[i]);
}
free(students);
注意单个字符的说明符是%c
,printf需要更正:
printf("Name: %s, Sex: %c, Age: %d\n", students[i]->name, students[i]->sex, students[i]->age);
// ^^
我要更改的另一件事是在 strncpy
中,而不是稍后用 null 终止字符串,我会让函数执行它:
// 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
已更正此处的问题是一种可能的替代方法,您可以使用它从 entry
一次性解析结构中的所有元素 sscanf
,如果您想要:
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;
}
您代码中的另一个问题是您使用“%s”作为性别,因为性别是唯一的字符。您应该使用 %c,否则 printf 函数将尝试解析字符串并获得 SEGFAULT。
我也劝你严格检查每一个内存分配。总是。
根据我的 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]=='[=10=]'||entry[k]=='\n')
{
newString[ctr][j]='[=10=]';
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])] = '[=10=]';
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);
}