【问题标题】:What are the pros & cons of using an array of structures versus an array of pointers to a structure?使用结构数组与指向结构的指针数组的优缺点是什么?
【发布时间】:2012-02-18 08:13:46
【问题描述】:

我正在尝试决定我应该使用哪个。

我能想到的结构指针的优点。

  • 如果您不使用数组的所有元素,则浪费的空间更少。
  • 交换数组元素时听到较少的声音

双方还有其他的优点/缺点吗?

【问题讨论】:

  • 您有什么要求?你知道编译时数组中有多少元素吗?数组中元素的交换频率如何?结构的重量有多大,复制性能值得关注?
  • 这个问题太模糊了,没有用。答案本质上是“学习 C 编程”的一整章。这相当于询问购买打印机与购买显示器的优缺点。两者都输出东西,但它们是不同的。
  • @KerrekSB 问这两种情况有什么不同有什么问题?我发现这些答案很有用,我希望将来有问题的其他人也能这样做。
  • @Michael:嗯,这是一个非常广泛的问题,所以它会是相当开放的。关于这个问题可以说很多,所以不清楚一个完整的答案应该是什么样子。当然,这是一个完全有效的问题,但 SO 不鼓励提出教程式和开放式答案的问题。

标签: c arrays pointers struct structure


【解决方案1】:

这些方法还有一些其他区别:

  • 指针数组方法减少了调整数组大小的开销;
  • 指针数组方法为您提供“空”/“未使用”值 (NULL)。如果这在您的应用程序中在语义上是有效的,那么这是一个优势(您不必更改 struct 本身来表达这一点);
  • 指针数组方法允许数组的多个元素引用同一个struct 而不是副本。同样,只有当这种情况对您的应用程序而言语义合理时,这才是一个优势;
  • 结构数组方法提供了更多的局部引用(structs 在数组中靠得很近,在内存中也靠得很近,这在某些情况下可能是性能优势);
  • 对于非常多的项目,结构数组方法需要大的连续内存块,如果您的进程地址空间变得碎片化,则可能无法使用。

【讨论】:

    【解决方案2】:

    使用指针数组或一般指针的缺点是:

    指针将(很可能)涉及使用动态内存分配,这意味着手动管理此动态内存。
    动态内存分配比堆栈分配慢一点。
    此外,使用动态内存更容易出错。

    话虽如此,实际上选择哪一个取决于:

    • 您的结构有多大
    • 编译时所需的结构数量是否已知
    • 您需要多久更换一次结构

    【讨论】:

    • 投反对票者:请解释投反对票的原因,或者不要匿名滥用你投反对票的权利。
    • 两个原因,如果您知道自己在做什么,动态内存既不会变慢也不会更容易出错。静态和动态内存都有自己的缺陷。
    • @LieRyan:动态内存比堆栈慢是一个很好的事实。至于容易出错的问题,我的回答是更容易出错希望你能分辨出来。
    • @AIs:尝试创建一种排序算法,该算法可以比指向结构的指针数组更快地对非平凡结构数组进行排序。如果使用得当,任何一个都可以比另一个更快。至于静态内存不易出错的说法,这是不正确的,静态内存只是有自己的陷阱,例如您不能返回静态分配的对象,或者您可能不必要地复制结构,或者您可能(意外地)在调用函数时进行复制,因此您对对象的修改不会反映给调用者。如果您不知道何时使用其中一种,这些都是常见错误。
    【解决方案3】:

    这里有一个重要的区别,一个结构数组需要一个大小为 sizeof(struct)*n 的连续内存块,另一方面,一个指向结构的指针数组,但它仍然需要连续内存数组本身,每个结构不一定要紧挨着,所以前者需要很大的内存块,后者会导致更多的碎片,你的选择。

    另外,有人提到将结构数组写入磁盘更容易,这是真的,因为您只需要调用一次 write,带有指向第一个元素的指针和 sizeof(struct)*n,如果使用一个指针数组,您必须分别循环和写入每个元素。

    编辑:当然,您需要在循环中为指针数组分配每个结构。希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      如果您必须将数据写入磁盘,或通过套接字发送出去,或将其置于共享内存中(嵌入式实时应用程序中的所有非常常见的任务),数组可以稍微简单一些。

      数组避免使用malloc().,但它们通常需要realloc(),,如果数组很大并且内存空间碎片化,这可能是一个问题。当然realloc()不适用于.bss,.text.中的数组,期待其他答案。好问题。

      【讨论】:

      • 请记住,realloc 是用于通过malloc 分配的动态内存,而不是用于在堆栈或静态分配的内存中声明的数组...
      • 和 Als 一样,我也刚刚收到了一个奇怪的反对票。我同意这可能不是世界上最出色的答案,但来吧......
      • @Jason:很好的警告。无法扩展 .bss, afaik,我希望没有人想要 realloca() 函数!
      【解决方案5】:

      一个可能的缺点是,对于程序员来说,使用指针会增加开销。您需要确定您的项目目标是什么。

      如果您不打算进行大量排序和交换,并且您有足够的内存并且不打算将其最大化,那么您需要问自己是否值得使用指针来头疼。

      【讨论】:

      • 我猜投反对票的人认为我们应该始终以最困难的方式做事,即使我们只是处理一个包含 12 个元素的数组?想要详细说明?
      【解决方案6】:

      指针数组需要空间来存储指针和结构。另一方面,如果不同的结构包含不同但不变的有意义数据量,则使用指向结构的指针将允许为它们分配不同量的空间。在某些情况下,由此节省的空间可能超过额外指针的成本。

      在许多情况下,使用指针数组访问结构需要对每个结构访问进行额外的查表步骤,而使用结构数组则需要额外的乘法运算。在许多较新的架构上,乘法比查表便宜,但在一些较小或较旧的架构上,情况正好相反。此外,一些较小或较旧的体系结构可能难以处理跨越某些内存边界的对象。即使在无法分配超过 80 字节数组的架构上,也可以分配 8 个 20 字节结构指针的数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-03
        • 2012-12-07
        • 2016-06-20
        相关资源
        最近更新 更多