【问题标题】:A Simple Object System一个简单的对象系统
【发布时间】:2014-04-01 09:51:35
【问题描述】:

我正在学习学习c the hard way这本书,并且在练习19中遇到了一些问题。作者说ex19是为了让学习者了解c中的宏。我理解这个概念没有问题,但我就是不理解其他所有内容。我无法理解对象原型是如何创建的。

特别是,下面的句子是什么意思?

由于 C 将 Room.proto 字段放在首位,这意味着 el 指针是 真的只指向足够的内存块才能看到完整的 对象结构。它不知道它甚至被称为原型。

相关代码是这样的:

// 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. 谁能告诉我malloc/calloc到底是如何工作的?据我所知,它只是分配所需数量的内存并返回第一个地址。如果是这样,计算机如何知道分配的内存的数据结构?就像代码中的Room *arena = NEW(Room, "The arena, with the minotaur");之后,你可以直接这样做arena->bad_guy = NEW(Monster, "The evil minotaur");电脑怎么知道有bad_guy??
  2. 在上面两个语句(Object *el = calloc(1, size);*el = proto;)之后*el的内容到底是什么?

任何帮助将不胜感激!

练习链接:http://c.learncodethehardway.org/book/ex19.html

【问题讨论】:

    标签: c malloc calloc


    【解决方案1】:

    calloc 具有一个附加功能,它用零字节填充分配的内存,而使用等效的malloc 调用将需要额外的步骤,如果所有或部分分配最初需要为零。

    在代码中

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

    编译器知道结构的布局,因为访问是通过 arena 变量进行的,该变量被声明为指向 Room 的指针,可能是结构的 typedef

    另一方面,结构内的顺序保证允许复合结构或扩展结构中的有限形式的继承

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

    struct B(或指向它的指针)可以转换为(指向a的指针)struct A,因为它们都以int开头。当然,如果你以另一种方式转换,struct A 必须最初是一个struct B,否则对baloney 字段的访问将是未定义的。换句话说,struct B 本质上以struct A 开头。

    如果我像这样重写我的示例,这可能更容易看到:

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

    现在您可以通过不同的方式从struct B 中获得struct A

    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
    

    【讨论】:

    • 谢谢!我明白了一点......但我只想知道Object *el = calloc(1, size);是什么意思,当正常的做法是Object *el = calloc(1, sizeof(Object));,以及你这样做之后在内存中发生了什么*el = proto;,因为el指向的是比 proto 需要的更大。
    • 由于calloc用零字节填充内存,内存中的结果将是proto的值后跟零字节直到size。在我的示例中,struct Astruct B 的真子集,因此struct B 始终可以像struct A 一样使用。它们包含相同的前缀,int。本质上,struct B包含 struct A 开头,即使成员变量有不同的名称。
    • 非常感谢您的快速回答!我想我明白了,非常感谢!
    【解决方案2】:

    它所做的只是分配1*size 字节。 malloc/calloc 没有什么神奇之处。他通过那个 NEW 宏将 sizeof(T) 传递给函数,并将其放入 Object_new 的 size 参数中。所以函数只知道字节大小。

    【讨论】:

    • 内存“malloc”的类型由您分配返回值的指针类型暗示。 malloc 的大小由“malloc”例程存储在某处(通常在返回地址之前的内存中),这就是“free”如何神奇地知道调用时要返回多少内存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 2011-09-01
    相关资源
    最近更新 更多