指针数组与元素数组

Har*_*rdy 4 c arrays pointers memory-management

今天早上我和同事就这个话题进行了讨论.他说,将数组分配为指针数组总是更好,因为分别分配每个元素有更好的机会获得一个空闲的内存块.有人这样想:

// Consider n_elements as a dynamic value
int n_elements = 10, i;
int **ary = (int **) malloc(sizeof(int *) * n_elements);

for(i = 0; i < n_elements; i++)
{
  ary[i] = (int *) malloc(sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)

与他的方法相反,我认为分配元素数组更好,只是因为你会得到一个紧凑的内存块而不是堆在堆中的一堆引用.像这样的东西:

int n_elements = 10;
int *ary = (int *) malloc(sizeof(int) * n_elements);

ary[0] = 100;
Run Code Online (Sandbox Code Playgroud)

在这次谈话之后我一直在思考它,我的最终结论是它取决于它.由于上面提到的原因,我在处理小数据类型时发现第二种解决方案是更好的方法,但是当分配大型结构的数组时,第一种可能更好.

除了我的结论,你怎么看待它?

Jus*_*ers 6

对于我能想到的任何主流硬件,他都错了.(至少一般而言).它可能会有所不同,可能会有一些特殊情况.尽可能在指针数组上选择元素数组.

像数据一样的CPU缓存是连续打包的.分别分配每个元素将增加缓存未命中,减慢分配时间和浪费内存(由于分配对齐).CPU速度和内存之间的差距每年都在增长,从而增加了连续打包数据和批处理操作的优势.

您应该阅读本问题中描述的文档,每位程序员应该了解的内存.它详细描述了现代CPU /内存关系的所有细节,以及为什么连续数据非常重要.

  • 例外是一个大型的,稀疏访问的数组,每个条目最好可能在它引用的其他东西附近分配.但这取决于有一个堆可能会在地址附近分配近实时的东西. (3认同)
  • 而且,对于用户定义的类型,如果巨大导致内存碎片 (2认同)
  • 还应注意,许多缓存每个分配都有一个缓存头,因此分别分配多个条目需要更多堆.另外,舍入到分配边界将需要更多堆来进行单独分配. (2认同)