简体   繁体   English

如何修复我的代码以从 function 返回指向结构的指针

[英]How to fix my code to return a pointer to a struct from a function

I'm learning pointers and struct now and I'm a bit confused.我现在正在学习指针和结构,我有点困惑。 Particularly, I want to make a function which returns a pointer to a struct.特别是,我想制作一个 function ,它返回一个指向结构的指针。 My code is compiling, but it isn't working.我的代码正在编译,但它不工作。 After I type the number of students, it asks for name and age (without reading name), and after I type the age, it closes.在我输入学生人数后,它会询问姓名和年龄(不读姓名),在我输入年龄后,它会关闭。

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

struct details
{
    char name[100];
    int age;
};

struct details * details_pointer(int n)
{
    struct details pointer_x[n];
    struct details *pointer = pointer_x;
    for (int i=0; i<n; i++)
    {
        printf("Student %d:\n", i);
        printf("name:\n");
        fgets(pointer[i].name, 100, stdin);
        printf("age:\n");
        scanf("%d", pointer[i]. age);
    }
    return pointer;
}

int main()
{
    int n;
    printf("Type the number of persons:\n");
    scanf("%d", &n);
    struct details *student = details_pointer(n);
    printf("\nName: %s\n", (*student).name);
    printf("Age: %d\n", (*student).age);
    system("pause");
    return 0;
}

The problem here is that you're returning a structure variable ( pointer_x ) that's allocated locally on the stack of the inner details_pointer() function, but this memory is no longer reserved for you once it returns.这里的问题是您返回的结构变量 ( pointer_x ) 在内部details_pointer() function 的堆栈上本地分配,但是这个 memory 一旦返回就不再为您保留。 This means you get (at best) garbage.这意味着您(充其量)得到垃圾。

You have to either allocate memory in the function and return it (and remember to free it.) or pass the data to the function to fill it in.您必须在function中分配 memory 并将其返回(并记住释放它。)或将数据传递给 function 以填充它。

void get_details(int n, struct details p[n])
{
  for (int i = 0; i < n; i++)
  {
    // do stuff with p[i]
  }
}

int main()
{
   ...
   scanf("%d", &n);
   struct details students[n];
   get_details(n, students);

   printf("\nName: %s\n", students[0].name);
   ...
}

I generally prefer passing data to the function when possible just because it simplifies memory management.我通常更喜欢在可能的情况下将数据传递function,因为它简化了 memory 管理。

EDIT: Two notes about your existing details_pointer() function.编辑:关于您现有的details_pointer() function 的两个注释。

1) In fgets(pointer[i].name, 100, stdin) , it's a good practice to derive the number of bytes from the size of the array if it's known; 1) 在fgets(pointer[i].name, 100, stdin)中,如果已知数组的大小,最好从数组的大小中导出字节数; in this case it is, so recommend fgets(pointer[i].name, sizeof(pointer[i].name), stdin) .在这种情况下,所以推荐fgets(pointer[i].name, sizeof(pointer[i].name), stdin) Yours is not incorrect, but it's easier to maintain should the sizes change in the future.您的并没有错,但是如果将来尺寸发生变化,维护起来会更容易。

2) the scanf("%d", pointer[i].age) needs to take the address of the .age to stuff its value in there; 2) scanf("%d", pointer[i].age)需要获取.age地址来填充它的值; you're passing a number instead of an address, which is for sure incorrect.您传递的是数字而不是地址,这肯定是不正确的。

Ok, so if the assignment requires dynamic allocation, then that's what we have to do.好的,所以如果分配需要动态分配,那么这就是我们必须做的。

Just specifying an array implicitly allocates the space while the function is running, but it disappears when the function returns.仅指定一个数组会在 function 运行时隐式分配空间,但当 function 返回时它会消失。 You'll need to allocate it specifically.您需要专门分配它。

Revisiting your code:重新访问您的代码:

struct details *details_pointer(int n)
{
    struct details *students = (struct details *)malloc(n * sizeof(struct details));

    .... do stuff with students[0] and the like

    return students;
}

This uses the malloc() - memory allocate - library function to get you some space, and it remains valid until you release it.这使用malloc() - memory allocate - library function 为您获取一些空间,并且在您释放它之前它一直有效。 The number of bytes is how many things you want ( n ) times how many bytes in one thing ( sizeof(struct details) )字节数是你想要多少东西( n )乘以一件东西的字节数( sizeof(struct details)

Later:之后:

int main()
{
    struct details *student = details_pointer(n);
    .. do stuff

    free(student);
}

This now uses that memory, and releases it back to the OS when you're done.现在使用memory,并在完成后将其释放回操作系统。

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

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