当前位置: 首页 > 知识库问答 >
问题:

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

蒙化
2023-03-14

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));
}

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

共有1个答案

苏鸿才
2023-03-14

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

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

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

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

在某些环境中,支持自定义分配器是很有用的。您可以向库的用户提供将指针传递到mallocreallocfree替代实现的选项。当您希望编写一个需要由本身完全可移植的代码使用的可移植库时,它非常有用。不过,大多数情况下,想要使用自定义分配器的用户可以通过链接自己的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;
    …
}
 类似资料:
  • 为什么不检查它是否可以分配内存? 摘自: 如果分配导致堆栈溢出,则程序行为未定义。…如果无法扩展堆栈帧,则没有错误指示。 现在和都返回一个指针,指向新分配的内存的开始,这意味着它们都必须知道堆栈/堆在当前时刻的结束位置。实际上,来自: 调用增量为0的sbrk()可以用来查找程序中断的当前位置。 因此,按照我的理解,检查是否可以分配所需的内存,本质上归结为检查堆栈的当前末端和堆的当前末端之间是否有足

  • 我在学计算机工程,我有一些电子课程。我从我的两位教授(这些课程)那里听说,可以避免使用函数(在、等之后),因为分配的内存空间可能不会再次用于分配其他内存。也就是说,例如,如果您分配4个字节,然后释放它们,您将有4个字节的空间,可能不会再次分配:您将有一个洞。 我认为这太疯狂了:你不可能有一个在堆上分配内存而不释放内存的非玩具程序。但是我没有知识来解释为什么它如此重要,对于每一个malloc()必须

  • 在C语言中,alloca()函数在alloca()调用方的stackframe上分配内存。 当您试图分配大量它无法分配的字节时,会发生什么? null 有人有更多关于这方面的信息吗?

  • 问题内容: 对齐是的,没关系,但是对齐的呢?是否保留对齐方式或如何确保重新分配的内存具有相同的对齐方式?假设Linux和x86_64。 问题答案: 不,ISO或POSIX不能保证返回的内存保持相同的对齐方式。A 可以 简单地将当前块扩展到相同的地址,但也可以将其移动到对齐方式比原始地址严格的其他地址。 如果您想要相同的对齐方式,则最好分配另一个块并复制数据。 不幸的是,在单一UNIX规范中也没有任

  • 我有这两个函数,我试图修改元素。其中一个编译,另一个说“val不能重新分配”。以下函数有什么区别?为什么一个编译,另一个不编译? 编译的那个 那个说 无法重新分配Val

  • 问题内容: 这是一篇受此评论启发的帖子,内容涉及如何在CPython中为对象分配内存。最初,这是在创建列表并将其添加到for循环中_以_ 实现列表理解的上下文中。 所以这是我的问题: CPython中有多少个不同的分配器? 每个功能是什么? 什么时候被正式称为?(根据此评论中的内容,列表理解可能不会导致调用, python在启动时会为其分配多少内存? 是否有规则来控制哪些数据结构在此存储器上首先获