繁体   English   中英

在C中为二维数组分配内存的最佳方法是什么?

[英]Best way to allocate memory to a two-dimensional array in C?

C分配内存到two-d array的最佳方法是什么: memory-managementspeed

另外,哪个更好用,一个two-d array (并为它分配内存)或一个double pointer 有人可以详细解释一下,内部会发生什么,为什么一种方法比另一种更好?

为了获得最佳性能和最佳可读性,应始终将此类数组分配为连续的内存块:

type (*array) [X][Y] = malloc( sizeof(type[X][Y]) );

你应该避免这个:

// BAD METHOD, not a real array

type** lookup_table = malloc( X*sizeof(type*) );
for(size_t i=0; i<Y; i++)
{
  lookup_table[i] = malloc( Y*sizeof(type) );
}

由于种种原因,前者更快。 它被分配在一个连续的内存块中,而不是在整个堆中进行分段。 分段版本阻止了所有形式的代码优化和高效的片上数据缓存使用,而且实际分配也慢得多。

上面的“坏”版本有一个优点,那就是当您希望单个维度具有可变长度时,例如在为字符串创建查找表时。 然后你必须使用那个表格。 但是如果你想要一个真正的2D阵列,那么就没有理由不使用前者。


请注意,第一个版本通常写为

type (*array) [Y] = malloc( sizeof(type[X][Y]) );

允许更方便的使用: array[i][j] ,而不是可读性较低的(*array)[i][j]

data_type (*mat)[size_2] = malloc(size_1 * size_2 * sizeof(data_type));

这将为一个数组(“2d数组”)分配连续的内存。 如果你不需要荒谬的1个空间,这就是你要走的路。 您将减少内存碎片,提高缓存友好性并避免因使用malloc而产生过多开销。


1 对于一些(特定于应用程序)的荒谬定义

给定一个固定的大小,你可以简单地说twoDimArray[100][100] ,它将在堆栈上分配它。 但是,在堆上分配时(无论是因为大小非常大还是因为大小是动态的),您有更多选项。

您可以分配一个指针数组,然后循环为每一行分配内存。 这对于缓存局部性来说是有问题的,但如果大小非常大并且您的访问是连续的,则非常好; 它允许合理数量的碎片而不会对性能产生巨大影响,因为阵列阵列可以与阵列本身分开,每个阵列可以彼此分开。 在线性访问场景中,您通常不会在内存区域之间跳转; 相反,你甚至可能在移动到一个新区域之前访问整行。

第二种方法是线性化访问并立即分配它们; 即,为sizex * sizey分配足够的内存,然后用(positiony * sizex) + positionx索引它; 也就是说,倒计数一些行然后跨越一些列。 这非常适合随机访问并改善缓存局部性,因为内存是连续的,但如果没有足够的连续内存可用,则可能会失败(如果需要比缓存更多的内存,则缓存局部性优势不适用)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM