C返回结构指针

C返回结构指针,c,pointers,struct,C,Pointers,Struct,假设我有一个这样的结构: struct Person { int age; char *name; Person *next_ptr; } 现在我有一个函数,它生成2个人并返回指向第一个结构的指针: Person *GetPerson(){ char[5] p1name = "John"; char[4] p2name = "Bob"; struct Person *p1; struct Person *p2; p2 = malloc(sizeof(struct P

假设我有一个这样的结构:

struct Person {
    int age;
    char *name;
    Person *next_ptr;
}
现在我有一个函数,它生成2个人并返回指向第一个结构的指针:

Person *GetPerson(){
char[5] p1name = "John";
char[4] p2name = "Bob";

struct Person *p1;
struct Person *p2;

p2 = malloc(sizeof(struct Person));
strcpy(p2.name, p2name);
p2->age = 25;

p1 = malloc(sizeof(struct Person));
strcpy(p1.name, p1name);
p1->age = 20;
p1->next_ptr = p2;

return p1;
}
以及使用函数来提取两个人

struct Person *person = malloc(sizeof(struct Person));
person = GetPerson();
int person1age = person.age; // Get age
char person1name[4] = person.name; // Get name
int *person2_ptr = person.next_ptr; // Extract the person 2 pointer

struct Person *person2 = malloc(sizeof(struct Person));
person2 = (*person2_ptr);
char person2name[4] = person2.name; // gets person 2 name
int person2age = person2; // get person 2 age
我希望我清楚地表明了我的意图。有人能告诉我正确的实施方法吗

struct Person p1;
应该是指针:

struct Person *p1;
同样,对于
p2

如果要访问结构中的字段,则不能执行以下操作:

p2.age = 25;
相反,您必须使用:

p2->age = 25;
因为
p2
现在是指针而不是实例。上述内容相当于:

(*p2).age = 25;

不幸的是,代码中有很多错误

一,。 在C中,与C++不同,每次想创建一个实例< <代码>结构>人>代码>时,你必须说<代码>结构>人<代码>,而不是<代码>人>代码> < /p> 二,。 在C语言中,声明大小为5的
char
数组的方法是
charp1name[5]
char[5]p1name

  • GetPerson()
    p1
    p2
    的主体内声明为指针,这意味着
    strcpy(p1.name,p1name)
    实际上应该是strcpy(p1->name,p1name) 甚至
    strcpy((*p1).name,p1name)如果您愿意
    更严重的问题:

  • 您必须注意,当您为
    struct Person
    的实例动态分配内存时,不会自动为
    char*名称分配内存;因为这个调用
    strcpy(p1->name,p1name)将失败。您可以保留
    char*
    并动态为其分配内存,但为了简单起见,我建议您选择一个大小合理的
    char
    数组

  • 请记住,
    GetPerson()
    struct Person
    的实例分配内存并返回指针。现在,在您的主要功能中,您有:

    struct Person *person = malloc(sizeof(struct Person)); //allocating memory in main
    person = GetPerson();  // you just leaked the memory you allocated in main
    
    您正在分配内存两次。这不会导致程序崩溃,但会导致需要避免的“内存泄漏”。您总是希望
    释放()
    动态分配的内存

  • 把这些放在一起,你会得到:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct Person {
        int age;
        char name[256];
        struct Person *next_ptr;
    };
    
    struct Person * GetPerson(){
        char p1name[5] = "John";
        char p2name[4] = "Bob";
    
        struct Person *p1;
        struct Person *p2;
    
        p2 = malloc(sizeof(struct Person));
        strcpy(p2->name, p2name);
        p2->age = 25;
        p2->next_ptr=NULL;
    
        p1 = malloc(sizeof(struct Person));
        strcpy(p1->name, p1name);
        p1->age = 20;
        p1->next_ptr = p2;
    
        return p1;
    }
    
    int main()
    {
        struct Person * tmp=GetPerson();
    
        printf(tmp->name); //prints John
        printf("\n");
        printf(tmp->next_ptr->name); //prints Bob
        printf("\n");
        free(tmp);
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    结构人{
    智力年龄;
    字符名[256];
    结构人*next_ptr;
    };
    结构Person*GetPerson(){
    字符p1name[5]=“John”;
    字符p2name[4]=“Bob”;
    结构人*p1;
    结构人*p2;
    p2=malloc(sizeof(struct Person));
    strcpy(p2->name,p2name);
    p2->年龄=25岁;
    p2->next_ptr=NULL;
    p1=malloc(sizeof(struct Person));
    strcpy(p1->name,p1name);
    p1->年龄=20岁;
    p1->next_ptr=p2;
    返回p1;
    }
    int main()
    {
    结构Person*tmp=GetPerson();
    printf(tmp->name);//打印John
    printf(“\n”);
    printf(tmp->next_ptr->name);//打印Bob
    printf(“\n”);
    免费(tmp);
    返回0;
    }
    

    请注意,这在逻辑上仍然不是很好的代码,但它没有bug

    您的主要问题是没有为保存人名本身的字符串分配空间。所以当你这么做的时候

    p2 = malloc(sizeof(struct Person));
    strcpy(p2->name, p2name);
    
    p2->name没有真正指向任何有意义的地方,事情就会失败。这里有两个选项,一个是使用两个malloc分别对结构和名称的足够空间进行malloc:

    p2 = malloc(sizeof(struct Person));
    p2->name = malloc(60); // deemed sufficient for name
    strcpy(p2->name, p2name);
    
    或者,您也可以将名称声明为数组,在这种情况下,通过将结构定义更改为:

    struct Person {
        int age;
        char name[60];
        Person *next_ptr;
    }
    

    在这种情况下,原始malloc也将为name分配空间。任何一个都应该有效。对于p2所说的一切也适用于p1。

    p1是堆栈上的
    struct Person
    。函数
    GetPerson
    被声明为返回一个Person*(假定Person是一个typedef to struct Person),该Person应该在堆上分配并返回。读一点,实际上您正在mallocing p1和p2,所以将它们调整为struct Person*。另外,发布一个完整的程序,并准确地说明什么不起作用,以及为什么在名称后面用括号括起来的字符数组。还要确保为字符串上的空终止符留出空间
    char p1name[5]=“John”
    doesn
    char p1name[5]
    由于索引为0而请求6个字符?否。它请求5个字节。您尚未为名称字符串分配空间。您没有返回第二个结构指针的方法。