Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A Simple Object System

Tags:

c

malloc

calloc

I'm working my way through the learn c the hard way book and have run into a few issues on Exercise 19. The author said that ex19 was intended for the learners to get to know the macro in c. I have no problem in understanding the concept of that, but I just don't understand everything else. I can't understand how the object prototype is created.

Especilly,what does the following sentense mean?

Since C puts the Room.proto field first, that means the el pointer is really only pointing at enough of the block of memory to see a full Object struct. It has no idea that it's even called proto.

the relevant code is this:

// this seems weird, but we can make a struct of one size,
// then point a different pointer at it to "cast" it
Object *el = calloc(1, size);
*el = proto;
  1. can anyone tell me how on earth malloc/calloc exactly works? As far as i know, it just allocate the required number of memory and return the first address. If so, how can the computer know the data struct of the allocated memory? like in the code, after Room *arena = NEW(Room, "The arena, with the minotaur");,you can do this directly arena->bad_guy = NEW(Monster, "The evil minotaur"); how does the computer know there is a bad_guy??
  2. what on earth is the content of *el after the above two statements(Object *el = calloc(1, size); and *el = proto;)?

Any help will be appreciated!!

the link to the exercise: http://c.learncodethehardway.org/book/ex19.html

like image 403
linuxfish Avatar asked Jun 22 '26 00:06

linuxfish


1 Answers

calloc has the additional feature that it fills the allocated memory with zero bytes, whereas using the equivalent malloc call would require an additional step if all or some of the allocation needs to be zero initially.

In the code

arena->bad_guy = NEW(Monster, "The evil minotaur"); 

the compiler knows the layout of the struct because the access is through the arena variable, which is declared as a pointer to Room, which is presumably a typedef of a struct.

For the other part, the guarantee of ordering within structs allows a limited form of inheritance in composite structs, or extended structs.

struct A {
    int x;
};

struct B {
    int foo;
    double baloney;
};

struct B (or a pointer to it) can be cast to a (pointer to a) struct A because they both begin with an int. Of course, if you cast the other way, the struct A must have been originally a struct B or access to the baloney field will be undefined. In other words, struct B essentially begins with a struct A.

This may be easier to see if I rewrite my example like this:

struct A {
    int x;
};

struct B {
    struct A foo;
    double baloney;
};

Now you can get a struct A out of struct B in different ways.

struct A a;
struct B b;

a = b.foo;  // regular member variable access

struct A *ap = &a;
struct B *bp = &b;

ap = (struct A *)bp;  // cast the pointer

ap = & b.foo;         // take a pointer from the member variable
ap = & bp->foo;       // take a pointer from the member variable via a pointer
like image 128
luser droog Avatar answered Jun 23 '26 15:06

luser droog



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!