- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
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
的用途。
实际上,库中有几种可能的动态内存管理方法。
最常见的方法是在需要时调用malloc
、realloc
和free
。这就是他们的目的。
在某些环境中,支持自定义分配器很有用。您可以为库的用户提供将指针传递给 malloc
、realloc
和 free
替代实现的选项。当您想要编写一个需要由本身完全可移植的代码使用的可移植库时,它很有用。不过,大多数时候,想要使用自定义分配器的用户可以通过链接他们自己的 malloc
和 friend 来实现。甚至 that 也很少有用。
如果您需要可以在没有动态分配的环境(例如安全关键环境)中工作的代码,那么您也不应该使用 alloca
。 alloca
比 malloc
更糟糕,因为它会导致不可预测的堆栈使用,并可能导致根本无法检测到或只能由程序检测到的堆栈溢出碰撞。如果您在函数中需要可变(或大量)的临时内存,请让用户将适当大小的缓冲区传递给您。
/** [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/
malloc 分配的内存可以用realloc 重新分配。 alloca 有类似的功能吗?当您不想在堆上分配内存并且需要多次分配变量堆栈内存时,重新分配堆栈内存可能很有用,例如在库函数中,您需要动态内存
考虑返回动态或自动数组。与 C 语言并不真正相关。 返回数组的常用技术是:A)被调用者在堆上分配并返回,B)调用者在堆栈上分配并传递给被调用者。 // A void caller(void) {
在使用 std vector 保存我的国际象棋引擎的移动列表后,我意识到因为国际象棋的平均因子为 35(即从典型位置开始大约 35 次合法移动), vector 的大小调整了很多,从而对移动生成器的性
这是两个重叠的问题——我想为大型数组尝试 alloca() 而不是在堆上分配动态大小的数组。这样我就可以提高性能而不必进行堆分配。但是,我的印象是堆栈大小通常很小?增加堆栈的大小以便我可以充分利用 a
当您总是可以在足够大的堆栈上分配一个固定大小的缓冲区以满足所有用途时,您为什么要使用 alloca() 呢?这不是反问... 最佳答案 如果缓冲区的大小在运行时变化,或者如果您只是有时需要它,它可能会
我读过很多地方说 alloca 已经过时,不应该使用,应该使用可变长度数组。 我的问题是:alloca 是否可以完全替换为可变长度数组? 在我的特定实例中,我有一些看起来像这样的东西: typedef
引用 BUGS 部分的第二段,来自 alloca(3) 的联机帮助页 On many systems alloca() cannot be used inside the list of argume
我正在尝试编写一个函数,该函数传递一个函数以用于分配作为其参数;它应该接受类型为 void *(*)(size_t) 的任何有效分配器。但是,当我尝试使用 alloca 作为分配器时,我遇到了奇怪的行
如何在 D、C 和 C++ 等语言中使用内联 x86 汇编器实现 alloca()?我想创建一个稍微修改过的版本,但首先我需要知道标准版本是如何实现的。从编译器读取反汇编并没有帮助,因为它们执行了很多
我想为我的玩具编译器设计一个 IR(如 LLVM IR),但我不知道alloca的目的是什么?指导进一步分析。其中优化alloca信息被使用? 最佳答案 The ‘alloca‘ instructio
我正在尝试实现自己的数学库,并且从 vector 开始。这个想法是给类一个指向数字数组的指针,然后复制数组并将其存储在私有(private)变量指针给出的数据地址中。首先,我使用了 alloca尝试为
在 C 中,alloca() 函数在 alloca() 的调用者的栈帧上分配内存。 当您尝试分配它不可能分配的大量字节时会发生什么? 它是否分配尽可能多的字节直到堆栈遇到堆段? 或者它根本不分配任何东
一般理论问题。 我正在尝试从源代码构建一个库(FFTW,如果有人关心的话,但这真的不重要),我注意到有一个选项可以禁用 alloca。 我知道使用 alloca 的危险,但我正在评估使用和不使用 al
这段代码 #include "alloca.h" String str = "abc"; unsigned int *i; void setup() { Serial.begin(9600);
我有一个智能指针类型,我想构造一个对象,该对象采用该类型的指针和一个计数(在运行时动态计算),并从堆栈中分配足够的内存来容纳该智能对象的许多实例指针指向。我似乎找不到实现此目的的正确语法;可能吗? 给
alloca() 在堆栈上而不是在堆上分配内存,如 malloc() 的情况。所以,当我从例程返回时,内存被释放。所以,实际上这解决了我释放动态分配内存的问题。释放通过 malloc() 分配的内存是
我需要在函数中记录一些消息,例如: void log(char* format, ...); 对于格式缓冲区有几种方法: 有一个固定大小的缓冲区。这不会导致溢出,但可能会截断消息。 void log1
我正在维护一个遗留的 C++ 应用程序,它似乎有一个缓慢的内存泄漏。我已经设法通过确保当前配置不再抛出任何异常来“修复”内存泄漏,并且我还可以触发泄漏并通过将其配置为导致许多异常来扩展它。 所有分配的
是否可以在复合语句中使用 alloca?示例: typedef struct { size_t len; char* data; } string_t; #define str_to_
我正在阅读嵌入式软件基础 - Where C and Assembly Meet (2001),看到了以下代码: FILE *OpenFile(char *name, char *ext, char
我是一名优秀的程序员,十分优秀!