在制作大缓冲区时,使用 malloc 分配缓冲区是否比使用静态分配的缓冲区更快?

PQC*_*aft 3 c memory performance

我正在尝试制作这样的数组:

char tmp[4][32768];
//code
Run Code Online (Sandbox Code Playgroud)

这是在一个函数中,我发现使这个数组全局化将提高程序的速度(不幸的是我不能保持这样,因为函数在遇到某些数据时会递归调用自身)。我想让这个功能更快,但我读过它malloc可能很慢。那么,保持这样或这样做会更快吗?:

char** tmp;
tmp = malloc(4 * sizeof(char*));
tmp[0] = malloc(32768);
tmp[1] = malloc(32768);
tmp[2] = malloc(32768);
tmp[3] = malloc(32768);
//code
free(tmp[0]);
free(tmp[1]);
free(tmp[2]);
free(tmp[3]);
free(tmp);
Run Code Online (Sandbox Code Playgroud)

dbu*_*ush 12

这不是快或慢的问题。这是你是否炸毁堆栈的问题。

您正在创建一个大小为 128K 的数组,这对于局部变量来说相当大,而局部变量通常位于堆栈中。如果您递归调用此函数,则每次调用的堆栈上还有 128K。只需几次递归调用就足以导致堆栈溢出,这可能会导致崩溃。

动态分配内存几乎是您唯一的选择。但是,您可以将其减少为单个分配:

char (*tmp)[32768] = malloc(4 * sizeof *tmp);
Run Code Online (Sandbox Code Playgroud)

这种分配是有效的,因为类型的 2D 数组char [4][32768]衰减为char (*)[32768]与上述类型匹配的类型的指针tmp。返回的内存malloc足以容纳 4 个类型的对象char[32768]。该内存是连续的,与malloc为每个子数组分别调用 4 次不同。

  • @PQCraft 这听起来像是“goto”的一个很好的用例。 (3认同)
  • @PQCraft 这将使您的数组不相交,这可能会影响访问它的速度。答案中的方法使用单个连续的内存块,就像二维数组一样。 (3认同)
  • 由于 `sizeof (char)` 保证为 1,所以我相信 `malloc(4 * 32768)` 相当于 `malloc(4 * sizeof (char [32768])`。 (2认同)
  • @mediocrevgetable1 做得更好,使用取消引用的变量而不是类型。 (2认同)
  • @MichaelDorgan,它不是一个指针数组,而是一个指向 32768 个“char”数组的指针,这要归功于“()”和运算符优先级。希望这能澄清事情(刚刚注意到答案编辑,这更好地解释了它)。 (2认同)
  • @JérômeRichard 除非是 VLA,否则不会评估“sizeof”的操作数。它只是观察其类型并在编译时计算。 (2认同)