C中具有自引用结构的内存体系结构
Memory architecture with self reference structure in C
我有一个名为 container
的结构。
这个结构有一个名为 obj_mem
的 void 类型的指针,它将指向一些分配的内存。
由于此内存必须能够保持不同的结构,因此我跟踪地址和它包含的每个元素的类型(adress_obj
、type_obj
)以进行访问和转换。
最后一个 属性 我的 container
结构是它有一个自引用 child
.
因此在 运行 时间,用户可以创建 children 容器并向其添加 object。
typedef enum tob{ //type of object
obj1, obj2, obj3, obj4 ...
}t_tob;
typedef struct obj1{
//declare some stuff
}t_obj1;
typedef struct obj2{
//declare some stuff
}t_obj2;
typedef struct obj3{
//declare some stuff
}t_obj3;
typedef struct obj4{
//declare some stuff
}t_obj4;
typedef struct container{
int name_size;
char* name;
int nmbr_obj;
t_tob* type_obj;
char* adress_obj;
void* mem_obj;
int nmbr_child;
struct container* child;
}t_container;
然后我有一个处理整个数据的函数:
它处理容器 obj_mem
中的 object。
然后遍历他的 children 并处理他们的 object。
然后遍历他的children的children,处理他们的
object
等等...直到树的尽头。
问题:
我是编程新手,我不确定这是正确的方法。
这段代码会导致大量的 malloc 调用,所以内存不会连续,这是一个问题吗?
有没有更优雅的方式来做这种动态类型的事情?
你有什么书可以帮助我更多地了解这种内存架构吗?
如果这个 post 看起来有点模糊,我很抱歉,但这就是我现在的感受。
感谢您的帮助。
如果您的容器必须保存数据树,则在某种形式下非常需要这样的结构。真正奇怪的一件事是您的对象成员类型是一个指针,通常是一个简单的值。
the memory won't be contiguous, is this a problem ?
这不是问题,但会影响性能。
使用更好的内存局部性(连续内存而不是碎片内存)有助于 CPU 利用它的缓存并最大限度地减少缓存未命中,这在性能方面可能是一件非常重要的事情。
但这并不是最重要的部分。你总是可以稍后优化它。最重要的部分是数据结构实际上做了它需要做的事情。
Is there any more elegant way of doing this dynamic type of things ?
可能吧,但我不确定你想做什么,所以我帮不了你。
通常在编写动态类型系统时,object 的类型是 object 的一部分,即:
struct my_object_s {
unsigned int type;
/* common type data*/
struct vtable_s * vtable;
};
struct my_string_s {
struct my_object_s header;
size_t len;
char str[];
}
这允许 object 独立于它的容器。
Do you have any books who could help me learning more on this kind of memory architecture ?
我在互联网上阅读了我所知道的大部分内容(我确实有几本书,但其中没有多少涉及硬件架构)。
编辑(回复评论)
您可以找到关于 Object 使用 C here 的面向编程的更全面的信息。作者做了大量工作来解释这些概念,并且在创作动态类型时经常(部分或全部)使用这些相同的想法。
例如,通过使用虚函数 table,可以完全避免转换。
另一方面,当您的类型集有限时,通常使用 switch 语句。
enum my_type_enum {
/** A simple flag object object (`my_object_s`) for NULL. */
MY_NULL,
/** A simple flag object (`my_object_s`) for OK. */
MY_OK,
/** A simple flag object (`my_err_s`) that indicates an error. */
MY_ERR,
/** A Number object object (`my_number_s`). */
MY_NUMBER,
/** A String object (`my_string_s`). */
MY_STRING,
/** An Array object object (`my_array_s`). */
MY_ARRAY,
};
typedef struct { enum my_type_enum type; } my_object_s;
typedef struct {
my_object_s header;
size_t len;
char str[];
} my_string_s;
void example_usage(my_object_s *obj) {
switch (obj->type) {
case MY_STRING:
printf("String: %s", ((my_string_s *)obj)->str);
break;
default:
printf("whatever...");
}
}
请注意,通过将 my_object_s
作为每个类型的 header,您可以安全地访问 header 数据,就像任何指向 object 的指针一样是一个 my_object_s *
,这样你就可以辨别它的基础类型。
我有一个名为 container
的结构。
这个结构有一个名为 obj_mem
的 void 类型的指针,它将指向一些分配的内存。
由于此内存必须能够保持不同的结构,因此我跟踪地址和它包含的每个元素的类型(adress_obj
、type_obj
)以进行访问和转换。
最后一个 属性 我的 container
结构是它有一个自引用 child
.
因此在 运行 时间,用户可以创建 children 容器并向其添加 object。
typedef enum tob{ //type of object
obj1, obj2, obj3, obj4 ...
}t_tob;
typedef struct obj1{
//declare some stuff
}t_obj1;
typedef struct obj2{
//declare some stuff
}t_obj2;
typedef struct obj3{
//declare some stuff
}t_obj3;
typedef struct obj4{
//declare some stuff
}t_obj4;
typedef struct container{
int name_size;
char* name;
int nmbr_obj;
t_tob* type_obj;
char* adress_obj;
void* mem_obj;
int nmbr_child;
struct container* child;
}t_container;
然后我有一个处理整个数据的函数:
它处理容器 obj_mem
中的 object。
然后遍历他的 children 并处理他们的 object。
然后遍历他的children的children,处理他们的
object
等等...直到树的尽头。
问题:
我是编程新手,我不确定这是正确的方法。
这段代码会导致大量的 malloc 调用,所以内存不会连续,这是一个问题吗?
有没有更优雅的方式来做这种动态类型的事情?
你有什么书可以帮助我更多地了解这种内存架构吗?
如果这个 post 看起来有点模糊,我很抱歉,但这就是我现在的感受。
感谢您的帮助。
如果您的容器必须保存数据树,则在某种形式下非常需要这样的结构。真正奇怪的一件事是您的对象成员类型是一个指针,通常是一个简单的值。
the memory won't be contiguous, is this a problem ?
这不是问题,但会影响性能。
使用更好的内存局部性(连续内存而不是碎片内存)有助于 CPU 利用它的缓存并最大限度地减少缓存未命中,这在性能方面可能是一件非常重要的事情。
但这并不是最重要的部分。你总是可以稍后优化它。最重要的部分是数据结构实际上做了它需要做的事情。
Is there any more elegant way of doing this dynamic type of things ?
可能吧,但我不确定你想做什么,所以我帮不了你。
通常在编写动态类型系统时,object 的类型是 object 的一部分,即:
struct my_object_s {
unsigned int type;
/* common type data*/
struct vtable_s * vtable;
};
struct my_string_s {
struct my_object_s header;
size_t len;
char str[];
}
这允许 object 独立于它的容器。
Do you have any books who could help me learning more on this kind of memory architecture ?
我在互联网上阅读了我所知道的大部分内容(我确实有几本书,但其中没有多少涉及硬件架构)。
编辑(回复评论)
您可以找到关于 Object 使用 C here 的面向编程的更全面的信息。作者做了大量工作来解释这些概念,并且在创作动态类型时经常(部分或全部)使用这些相同的想法。
例如,通过使用虚函数 table,可以完全避免转换。
另一方面,当您的类型集有限时,通常使用 switch 语句。
enum my_type_enum {
/** A simple flag object object (`my_object_s`) for NULL. */
MY_NULL,
/** A simple flag object (`my_object_s`) for OK. */
MY_OK,
/** A simple flag object (`my_err_s`) that indicates an error. */
MY_ERR,
/** A Number object object (`my_number_s`). */
MY_NUMBER,
/** A String object (`my_string_s`). */
MY_STRING,
/** An Array object object (`my_array_s`). */
MY_ARRAY,
};
typedef struct { enum my_type_enum type; } my_object_s;
typedef struct {
my_object_s header;
size_t len;
char str[];
} my_string_s;
void example_usage(my_object_s *obj) {
switch (obj->type) {
case MY_STRING:
printf("String: %s", ((my_string_s *)obj)->str);
break;
default:
printf("whatever...");
}
}
请注意,通过将 my_object_s
作为每个类型的 header,您可以安全地访问 header 数据,就像任何指向 object 的指针一样是一个 my_object_s *
,这样你就可以辨别它的基础类型。