gpt4 book ai didi

alloca() 内存可以重新分配吗?

转载 作者:太空狗 更新时间:2023-10-29 17:18:14 26 4
gpt4 key购买 nike

malloc 分配的内存可以用realloc 重新分配。 alloca 有类似的功能吗?当您不想在堆上分配内存并且需要多次分配变量堆栈内存时,重新分配堆栈内存可能很有用,例如在库函数中,您需要动态内存,但又不想在堆上分配,因为库的用户可能使用自定义堆分配策略。它看起来像这样:

int main(void) {
float * some_mem = alloca(40 * sizeof(float));
// do something with this memory...

// now we need a different amount of memory, but some_mem still occupies a lot of the stack, so just reallocate it.

// is something like this possible?
some_mem = realloca(some_mem, 50 * sizeof(float));
}

重要的是这一切都发生在堆栈上。 问:有没有办法重新分配动态堆栈内存?

最佳答案

不:这不适用于通常实现的堆栈。堆栈上的变量占用固定范围的地址。下一个变量紧随其后,因此没有增长空间。考虑这样一个函数:

void f(int x) {
int i;
float *a = alloca(40 * sizeof(float));
int k;

}

函数序言之后的堆栈看起来像这样:

----------------+-----+-----+-----+-------------------+-----+---------------------
... | ret | x | i | a | k | ...
----------------+-----+-----+-----+-------------------+-----+---------------------
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
previous frames f's frame free space at the top

a 没有增长空间。

我展示了一个高度简化的例子:在现实世界中,变量最终进入寄存器,变量可以重新排序,即使它们最终进入堆栈,等等。但是只有一个变量可以是最后一个堆叠有成长空间。

因此,如果 realloca 存在,它只能应用于堆栈顶部的变量。 (否则它必须移动它上面的所有其他东西,但这需要更新所有现有的指针,这通常是不可能的。)这将是一个非常有限的机制,因此对这个特性的支持将有一个很小的好处。支持它会产生巨大的成本,因为编译器通常可以按照他们想要的顺序自由地将东西放在堆栈上:这个特性需要一种新的机制来让编译器知道一个特定的变量必须到达顶部。

有可能某处的某些 C 实现具有 realloca,但考虑到成本/ yield 比,这不太可能。

当然,如果alloca 不使用堆栈分配策略,则realloca 可以很容易地实现。但是在堆栈上分配是 alloca 的重点。如果您想要可调整大小的对象,您需要一个带有堆接口(interface)的内存管理结构,这就是 malloc 的用途。


实际上,库中有几种可能的动态内存管理方法。

最常见的方法是在需要时调用mallocreallocfree。这就是他们的目的。

在某些环境中,支持自定义分配器很有用。您可以为库的用户提供将指针传递给 mallocreallocfree 替代实现的选项。当您想要编写一个需要由本身完全可移植的代码使用的可移植库时,它很有用。不过,大多数时候,想要使用自定义分配器的用户可以通过链接他们自己的 malloc 和 friend 来实现。甚至 that 也很少有用。

如果您需要可以在没有动态分配的环境(例如安全关键环境)中工作的代码,那么您也不应该使用 allocaallocamalloc 更糟糕,因为它会导致不可预测的堆栈使用,并可能导致根本无法检测到或只能由程序检测到的堆栈溢出碰撞。如果您在函数中需要可变(或大量)的临时内存,请让用户将适当大小的缓冲区传递给您。

/** [documentation of the function] …
* working_buffer must point to an array of floats of 3*n elements.
*/
void f(size_t n, float *working_buffer);

更好的是,如果您有代码大小预算,传递数组大小并验证它。

/** [documentation of the function] …
* working_buffer must point to an array of floats of 3*n elements.
*/
int f(size_t n, float *working_buffer, size_t working_buffer_length)
{
if (working_buffer_length < 3 * n) return -EINVAL;

}

关于alloca() 内存可以重新分配吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56392957/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com