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

alloca()在内存级别上是如何工作的?

鲜于允晨
2023-03-14

我试图弄清楚alloca()实际上是如何在内存级别上工作的。在linux手册页中:

我知道实现细节可能留给操作系统之类的东西。但我想知道,总的来说,这是如何实现的。

共有1个答案

沈华皓
2023-03-14

是的,alloca在功能上等效于局部可变长度数组,即:

int arr[n];

还有这个:

int *arr = alloca(n * sizeof(int));

两者都为堆栈上int类型的n元素分配空间。每种情况下arr之间唯一的区别是:1)一个是实际的数组,另一个是指向数组第一个元素的指针;2)数组的生存期随着其所包含的作用域而结束,而alloca内存的生存期在函数返回时结束。

#include <stdio.h>
#include <alloca.h>

void foo(int n)
{
    int a[n];
    int *b=alloca(n*sizeof(int));
    int c[n];
    printf("&a=%p, b=%p, &c=%p\n", (void *)a, (void *)b, (void *)c);
}

int main()
{
    foo(5);
    return 0;
}
&a=0x7ffc03af4370, b=0x7ffc03af4340, &c=0x7ffc03af4320

BSD3可以追溯到70年代末,因此alloca是VLAs被添加到标准中之前的早期非标准化尝试。

今天,除非您使用的编译器不支持VLAs(如MSVC),否则实际上没有理由使用这个函数,因为VLAs现在是获得相同功能的标准化方法。

 类似资料:
  • 我在研究Linux内核对共享内存的限制 指定可分配的最大页数。把这个数字看作x,把页面大小看作P。我假设“x*p”字节是系统范围共享内存的限制。 现在,我编写了一个小程序来创建一个共享内存段,并在该共享内存段上附加了两次,如下所示

  • 通过查看shmget()的手动页面,我了解到shmget()调用在内存中分配了#个页面,这些页面可以在进程之间共享。 它是否要创建内核内存页,并将其映射到进程的本地地址空间?还是为该段保留了相同的进程内存页,并将为其他附加进程共享相同的内存页? 调用shmget()时,内核将保留一定数量的段/页。 调用shmat()时,保留的段映射到进程的地址空间/页。 当一个新进程附加到同一段时,前面创建的内核

  • 据我所知,当我们创建时: JVM为其保留一部分连续的内存。当我们向列表中添加新元素时,当元素数量达到大小的75%时,它会保留一个新的连续内存部分并复制所有元素。 我们的名单越来越大。我们正在添加新对象,必须再次重建列表。 现在发生了什么? JVM正在寻找连续的内存段,但找不到足够的空间。 垃圾收集器可以尝试删除一些未使用的引用并对内存进行碎片整理。如果在此过程之后JVM无法为list的新实例保留空

  • 进程A使用shmget创建了一个共享内存“1234”。在此之后,进程A使用SHMAT将内存附加到自身。 “附加”到底是什么意思?是否存在同一内存的两个副本?如果没有,那么这个内存到底存在于哪里?

  • 问题内容: 据我所知,当我们创建一个时: JVM为此保留了内存的连续部分。当我们将新元素添加到列表中时,当元素数量达到75%时,它将保留新的连续内存部分并复制所有元素。 我们的名单越来越大。我们正在添加新对象,并且必须再次重建列表。 现在会发生什么? JVM正在寻找连续的内存段,但是找不到足够的空间。 垃圾收集器可以尝试删除一些未使用的引用和碎片整理内存。如果JVM在此过程之后无法为列表的新实例保

  • 考虑以下查询: 该查询将如何在Cassandra中“在引擎盖下”执行? 高基数列索引()将如何影响其性能? Cassandra会为上述查询接触所有节点吗?为什么? 先执行哪个条件,基表partition_key还是辅助索引partition_key?Cassandra将如何将这两个结果相交?