为什么不alloca
检查它是否可以分配内存?
来自man 3 alloca
:
如果分配导致堆栈溢出,则程序行为未定义。… 如果堆栈帧无法扩展,则没有错误指示。
为什么alloca
不/不能检查它是否可以分配更多内存?
我理解它alloca
在堆栈上分配内存时在堆栈上分配内存的方式(s)brk
。来自https://en.wikipedia.org/wiki/Data_segment#Heap:
堆区由 malloc、calloc、realloc 和 free 管理,可以使用 brk 和 sbrk 系统调用来调整其大小
来自man 3 alloca
:
alloca() 函数在调用者的堆栈帧中分配 size 个字节的空间。
并且堆栈和堆正朝着收敛的方向增长,如下图所示:
(上图来自Dougct 在CC BY-SA 3.0下发布的Wikimedia Commons)
现在两者都alloca
返回(s)brk
一个指向新分配内存开头的指针,这意味着它们都必须知道当前堆栈/堆在哪里结束。确实,来自man 2 sbrk
:
以 0 为增量调用 sbrk() 可用于查找程序中断的当前位置。
因此,按照我的理解,检查是否alloca
可以分配所需的内存基本上归结为检查堆栈的当前端和堆的当前端之间是否有足够的空间。如果在堆栈上分配所需的内存会使堆栈到达堆,则分配失败;否则,它会成功。
那么,为什么不能使用这样的代码来检查是否alloca
可以分配内存呢?
void *safe_alloca(size_t size)
{
if(alloca(0) - sbrk(0) < size) {
errno = ENOMEM;
return (void *)-1;
} else {
return alloca(size);
}
}
这对我来说更令人困惑,因为显然(s)brk
可以进行此类检查。来自man 2 sbrk
:
brk() 将数据段的末尾设置为 addr 指定的值,当该值合理时,系统有足够的内存,并且进程不超过其最大数据大小(参见 setrlimit(2))。
所以如果(s)brk
可以做这样的检查,那为什么不能alloca
呢?