Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

define a function returning struct pointer

Tags:

c

Please bear with me, i m from other language and newbie to c and learning it from http://c.learncodethehardway.org/book/learn-c-the-hard-way.html

struct Person {
    char *name;
    int age;
    int height;
    int weight;
};

struct Person *Person_create(char *name, int age, int height, int weight)
{
    struct Person *who = malloc(sizeof(struct Person));
    assert(who != NULL);

    who->name = strdup(name);
    who->age = age;
    who->height = height;
    who->weight = weight;

    return who;
}

I understand the second Person_create function returns a pointer of struct Person. I don't understand is(may be because i m from other language, erlang, ruby), why does it define it as

struct Person *Person_create(char *name, int age, int height, int weight)

not

struct Person Person_create(char *name, int age, int height, int weight)

and is there other way to define a function to return a structure?

sorry if this question is too basic.

like image 657
allenhwkim Avatar asked May 04 '12 15:05

allenhwkim


4 Answers

It is defined so because it returns a pointer to a struct, not a struct. You assign the return value to a struct Person *, not to struct Person.

It is possible to return a full struct, like that:

struct Person Person_create(char *name, int age, int height, int weight)
{
    struct Person who;
    who.name = strdup(name);
    who.age = age;
    who.height = height;
    who.weight = weight;
    return who;
}

But it is not used very often.

like image 159
MByD Avatar answered Oct 12 '22 09:10

MByD


The Person_create function returns a pointer to a struct Person so you have to define the return value to be a pointer (by adding the *). To understand the reason for returning a pointer to a struct and not the struct itself one must understand the way C handles memory.

When you call a function in C you add a record for it on the call stack. At the bottom of the call stack is the main function of the program you're running, at the top is the currently executing function. The records on the stack contain information such as the values of the parameters passed to the functions and all the local variables of the functions.

There is another type of memory your program has access to: heap memory. This is where you allocate space using malloc, and it is not connected to the call stack.

When you return from a function the call stack is popped and all the information associated with the function call are lost. If you want to return a struct you have two options: copy the data inside the struct before it is popped from the call stack, or keep the data in heap memory and return a pointer to it. It's more expensive to copy the data byte for byte than to simply return a pointer, and thus you would normally want to do that to save resources (both memory and CPU cycles). However, it doesn't come without cost; when you keep your data in heap memory you have to remember to free it when you stop using it, otherwise your program will leak memory.

like image 31
Baldur Þór Emilsson Avatar answered Oct 12 '22 10:10

Baldur Þór Emilsson


The function returns who, which is a struct Person * - a pointer to a structure. The memory to hold the structure is allocated by malloc(), and the function returns a pointer to that memory.

If the function were declared to return struct Person and not a pointer, then who could also be declared as a structure. Upon return, the structure would be copied and returned to the caller. Note that the copy is less efficient than simply returning a pointer to the memory.

like image 38
Adam Liss Avatar answered Oct 12 '22 09:10

Adam Liss


Structs are not pointers (or references) by default in C/C++, as they are for example in Java. Struct Person Function() would therefor return struct itself (by value, making a copy) not a pointer.

You often don't want to create copies of objects (shallow copies by default, or copies created using copy constructors) as this can get pretty time consuming soon.

like image 44
dbrank0 Avatar answered Oct 12 '22 11:10

dbrank0