Struct on the stack (Ex. 16)

Really looking forward to learn from this one. I feel that anything memory-related is worth knowing. Here is my code. Can you give me some helpful hints on what I am doing wrong, and where I might need to look? I did research what you asked.

OK, don’t trust me too much on this – I’m just a few exercises ahead of you. But I think I can spot a few things.


(6) You are making a new type, but later on you still refer to struct Person instead of just Person. Either use only Person afterwards or add Person at the end of the line to give the struct a name: typedef struct Person {...} Person;.

(8, 14) The brackets that declare that something is an array go after the identifier, not the type. char[] name is wrong, char name[] is right. In this case though you’ll want to use the pointer version of a string, because C needs to know how big the struct will be, and a character pointer has a fixed size: char *name.

(14) Person_create
Alright, you keep your struct on the stack, but you still need to create one and bind it to a variable – the declaration at the beginning of the file is just a “blueprint”. Also, Person.name is a reference to the name variable inside the struct, but this line on its own doesn’t assign anything. Try this:

Person Person_create(char *name, int age, int height, int weight)
{
    // declare a new variable that holds a Person
    Person new;
    // assign the values to the struct one by one
    // new.x is the variable in the struct,
    // ... = x is the value you pass to the function
    new.name = name;
    new.age = age;
    new.height = height;
    new.weight = weight;
    // return the newly created struct
    return new;
}

You could also create and populate your new person in one line: Person new = { name=name, age=age, ... };

(22) Get rid of Person_destroy. You don’t need it here because you can only free memory on the heap. Memory on the stack is freed automatically when the function exits.

(37) Here things got mixed up a little. abby is the variable that holds whatever Person_create returns. But Person_create is just an ordinary function that receives some arguments. The function call must match the signature on line 14. You cannot use abby in the function arguments because that function will create abby in the first place, and you don’t need to, because the function will do the assignments. Try this:

Person abby = Person_create("Abby Jones", 47, 75, 300);

(43) %p needs a memory address: use &abby at the end of the line.


I hope this helps a little! I hope @zedshaw will chime in…

2 Likes

Interesting. It’s almost like you are kind of mixing the concepts of heap allocation with the concepts of C’s struct allocation. First up, I’m just typing this raw into my laptop at 4am so I have no promises this code works.

First, you have code that you totally don’t need if you go with C’s allocation of structs. You can just write this:

struct Person abby = {.name = "Abby Jones", .age = 47, .height = 75, .weight = 300};

And you’re done. Time to move on with your life. That’s it. No free, no alloc, no extra function doing the exact same thing, nothing.

However, if you want to go the “allocate structs on the heap” way, then you need your functions, but you’re calling them wrong. There’s also a hybrid approach I’ll hint at in a minute, but to do this style you need:

  1. calloc enough memory for the C struct with sizeof(struct Person)
  2. Set all the struct members based on function variable inputs and using pointers not dots.
  3. Return the pointer you got from calloc.

In that style you then need Person_free, and you’d need to also copy all input strings, and free them as well. You can’t just set new->name = name, but have to do new->name = strcpy(name) but even that’s got problems. Just go with that for now then read up on how terrible strcpy is.

What’s the hybrid aproach? You are soooooooo close to stumbling on this so I’m just going to leave one line of code here to see if you can figure it out (assuming this code would work):

struct Person* abby = Person_new({.name = "Abby", .age = 47, .height = 75, .weight = 300});

Let your eyes linger on the { }…

1 Like

I completely understand the -> and the . notation differences now and was able to complete the assignment. I took a lot of time when went thru a few Udemy courses to get C down.

Love this language even more after understanding pointers.

struct Person abby;
   abby.name = "Abby Jones";
   abby.age = 48;
   abby.height = 75;
   abby.weight = 320;

Understanding the heap and the stack was also something that really clicked. Using malloc a lot helped me build up the muscle memory and also when and where to use it. I have not used calloc a lot, but I learned that calloc initialized the values in the memory block to zero. There was something about preventing overflow as well, which stuck with me.

Really enjoying the book now that I have had some time to get life stuff out of the way, settle down in my non-tech job, and just code for the sake of coding.

I will finish this book by the end of the year lol.

Thank you again for your detailed assistance. Always appreciated :smiley:

A free service run by Zed A. Shaw for learncodethehardway.org.