Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在结构中嵌入数组_C_Struct - Fatal编程技术网

C 在结构中嵌入数组

C 在结构中嵌入数组,c,struct,C,Struct,考虑两种定义结构的方法 typedef struct foo1 { int type; unsigned char* data; } ... struct *foo1 bla = malloc(sizeof(struct foo1)); bla->data = malloc(100); 及 我想foo2方法的优点是 我们保存sizeof(void*)字节的内存和 我们在访问bla->data时保存内存查找 foo1的优点是 在我们的结构中可以有任意数量的动态分配

考虑两种定义结构的方法

typedef struct foo1 {
    int type;
    unsigned char* data;
}

...

struct *foo1 bla = malloc(sizeof(struct foo1));
bla->data = malloc(100);

我想foo2方法的优点是

  • 我们保存
    sizeof(void*)
    字节的内存和
  • 我们在访问
    bla->data
    时保存内存查找
foo1的优点是

  • 在我们的结构中可以有任意数量的动态分配指针,而对于foo2,我们只能有一个(因为它必须是最后一个元素)
  • 用另一个指针覆盖
    bla->data
    更容易/更快
我的理解是,我希望检查是否正常,如果您计划构造数千个
fooN
s,并且您确定只需要一个动态分配的元素,那么您应该使用foo2方法,否则可读性和可扩展性方面的损失似乎不值得。这基本正确吗

<>编辑:我认为评论中的C++ SIDNONT非常有趣,不介意在这一点上进行详细阐述——如果使用<代码> FoO2意味着C++编译器将不接受你的代码,那么在做出决定时,这当然是需要考虑的,对吗? 我想foo2方法的优点是

  • 我们保存
    sizeof(void*)
    字节的内存和
  • 我们在访问
    bla->data
    时保存内存查找
是的,这是一些优势。您也只有一个分配,这很好,因为人们往往忘记释放第二个。更不用说,第二次分配的幕后存储开销可能超过
sizeof(void*)
字节

foo1的优点是

  • 在我们的结构中可以有任意数量的动态分配指针,而对于foo2,我们只能有一个(因为它必须是最后一个元素)
  • 用另一个指针覆盖
    bla->data
    更容易/更快
注意我是如何划掉第二点的?想想看。。。使用另一个指针覆盖
bla->data
的唯一原因是调整其大小,在这种情况下,您编写了类似
void*temp=realloc(bla->data,new_size)的内容

foo2案例中的替代方案是什么<代码>无效*temp=realloc(bla,尺寸为*bla+新尺寸),是吗?这是一个较小的内存占用和一个稍微简单的表达式。。。我建议这可能会快一点,因为它对缓存更友好,但前提是您正在使用这些分配之一

这是一个复杂的答案。如果您计划分配数千个元素,则应该考虑数据结构的规范化形式(例如,您将设计一个商业数据库)。当您需要调整单个
bla[n]>数据的大小时,这需要很简单,但当您需要调整整个
bla数组的大小时,这也需要是一项简单的任务。这意味着
数据
成员应该是
bla
分配的单独分配。尽量减少你的分配;在这种情况下,您只需要其中两个,并在必要时继续使用
realloc
调整它们的大小

如今,大多数常见的家用台式机/笔记本电脑在处理数千件此类物品时几乎没有问题,甚至每件物品的大小高达数百KB

始终记住,编写代码以便于维护。启动探查器并确定以后在何处进行优化(以及是否正确优化)非常简单,这样您就可以减少不可读crud对代码的污染,并且不太可能错过目标


<>编辑:我认为评论中的C++ SIDNONT非常有趣,不介意在这一点上进行详细阐述——如果使用FO2,就意味着C++编译器将不接受您的代码,那么在做出决定时,这当然是需要考虑的,对吗? <>你的代码不会在C++中编译,不管怎样,因为C++没有隐含的<代码>空洞< /Cord>指针转换,你的例子需要使用<代码> MalOC …而且你不应该写C风格C++。我们已经向整个社区解释了为什么不。我将把这些信息作为练习留给你自己查找

请记住,第二次分配是免费的;)

我想foo2方法的优点是

  • 我们保存
    sizeof(void*)
    字节的内存和
  • 我们在访问
    bla->data
    时保存内存查找
是的,这是一些优势。您也只有一个分配,这很好,因为人们往往忘记释放第二个。更不用说,第二次分配的幕后存储开销可能超过
sizeof(void*)
字节

foo1的优点是

  • 在我们的结构中可以有任意数量的动态分配指针,而对于foo2,我们只能有一个(因为它必须是最后一个元素)
  • 用另一个指针覆盖
    bla->data
    更容易/更快
注意我是如何划掉第二点的?想想看。。。使用另一个指针覆盖
bla->data
的唯一原因是调整其大小,在这种情况下,您编写了类似
void*temp=realloc(bla->data,new_size)的内容

foo2案例中的替代方案是什么<代码>无效*temp=realloc(bla,尺寸为*bla+新尺寸),是吗?这是一个较小的内存占用和一个稍微简单的表达式。。。我建议这可能会快一点,因为它对缓存更友好,但前提是您正在使用这些分配之一

这是一个复杂的答案。如果您计划分配数千个元素,则应该考虑数据结构的规范化形式(即L)。
typedef struct foo2 {
    int type;
    unsigned char data[]; //note: last element, so we can malloc dynamically
}

...

struct *foo2 bla = malloc(sizeof(struct foo2) + 100);