簡體   English   中英

C返回struct指針

[英]C return struct pointer

假設我有一個像這樣的結構:

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;
}

並使用該函數來提取Person。

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

我希望我明確表示我要做的事情。 有人能告訴我實現這個的正確方法嗎?

不幸的是,您的代碼中存在很多錯誤。

1.在C中,與C ++不同,每次要創建struct Person的實例時,都必須說struct Person ,而不是Person

2.在C中,聲明大小為5的char數組的方法是char p1name[5]; 不是char[5] p1name;

  1. GetPerson()體內, p1p2被聲明為指針,這意味着strcpy(p1.name,p1name); 應該是strcpy(p1->name,p1name); 甚至是strcpy((*p1).name,p1name); 如果你更喜歡。

更嚴重的問題:

  1. 您必須注意,當您為struct Person的實例動態分配內存時,不會自動為char * name;分配內存char * name; ; 因為這個調用strcpy(p1->name,p1name); 將失敗。 您可以保留char*並為其動態分配內存,但為了簡單起見,我建議您只選擇一個相當大的char數組。

  2. 請記住, 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 

    你正在分配內存兩次。 這不會導致程序崩潰,但會導致“內存泄漏”,需要避免。 你總是希望free()動態分配內存。

把它放在一起,你得到這個:

#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;
}

請注意,這在邏輯上仍然不是很好的代碼,但它沒有錯誤。

struct Person p1;

應該是一個指針:

struct Person *p1;

同樣適用於p2

然后,當您想要訪問結構中的字段時,您不能這樣做:

p2.age = 25;

相反,你必須使用:

p2->age = 25;

因為p2現在是指針而不是實例。 以上相當於:

(*p2).age = 25;

您的主要問題是您沒有為包含此人姓名的字符串分配空間。 所以,當你這樣做

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

p2-> name並沒有真正指向任何重要的東西,事情就會失敗。 這里有2個選項,一個是malloc結構和足夠的空間,分別用2個mallocs:

p2 = malloc(sizeof(struct Person));
p2->name = malloc(60); // deemed sufficient for name
strcpy(p2->name, p2name);

或者,您將name聲明為數組,在這種情況下,它將通過將結構定義更改為:來分配自己的空間:

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

在這種情況下,原始malloc也將為名稱分配空間。 任何一個都應該工作。 無論對p2說什么,也適用於p1。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM