Structs and pointers

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

Can you explain this part. Created a function to add into struct right.So how does it replaces person_create with whatever variable we add like struct Person *joe. How to create same function without pointers. I’m getting error like below.

In file included from a.c:2:0:
/usr/include/stdlib.h:483:13: note: expected ‘void *’ but argument is of type ‘struct Person’
extern void free (void *__ptr) __THROW;
         ^
a.c: In function ‘Person_create’:
a.c:24:1: warning: control reaches end of non-void function [-Wreturn-type]
}

Person_create doesn’t add into a struct, it creates a struct to begin with and then populates the slots with data.

So when you do

Person *joe = NULL;
joe = Person_create("Joe", ...)

at first, joe is just a pointer that doesn’t point anywhere yet, but it has the type of the thing it will point to attached to it: struct Person.
In the second line Person_create makes a new struct Person and you assign its memory location to joe.

Now, if you don’t allocate the new struct on the heap (which is what I assume you mean by not using pointers), you can’t (and don’t need to) free it. Just get rid of that line and it should work.

Does that help?

At top its Person_create but inside function its who.I don’t understand how it replaces who with the name we type in place of Person_create.

Ah. It doesn’t "replace who".

The name of the variable we assign the new person to lives outside the function. That’s joe in my example above.

During creation, i.e. inside the function, our new person is held by who and when it’s finished it gets passed to joe in the outside world

struct Person *Person_create(char *name, int age,int height,int weight)
{
 struct Person who1;
 struct Person *who;
     who = &who1;
//assert(who != NULL);
who->name = name;
who->age = age;
who->height = height;
who->weight = weight;

return who;

}

One final doubt.I tried without malloc.It works but age and height isn’t printing correctly.

struct Person *Joe= Person_create("joe",24, 6, 70);


    Name:joe
        Age:4195882
        Height:0
        Weight: 70

This is a little upside-down.

Right now you are creating a person on the stack in Person_create, but you only return a pointer to that memory location, not the whole block. There are no garantees as to what happens at that memory location after the function exits. I suppose you would get different output each time you run this.

If you want to keep everything on the stack, you need to return the actual struct, not a just a pointer. Try this:

// Note that I declare a return type that is not a pointer
struct Person Person_create(const char *name, int age, int height, int weight)
{
    struct Person who;
    who.name = name;  // note the dot instead of -> for directly accessing struct slots
    who.age = age;
    who.height = height;
    who.weight = weight;

    return who;
}

// here I also create a struct, not a pointer to a struct
struct Person joe = Person_create("Joe", 24, 6, 70);
A free service run by Zed A. Shaw for learncodethehardway.org.