问题:C99 中 数组的长度可以动态申请,底层是如何实现的?(我不确定是不是C99)
学过一点函数堆栈图,函数开栈的时候要知道自己要开多大的空间,这就要知道这个函数体中的所有变量要用多大的空间(不是new 、malloc 出来的变量在函数开的栈中),之前做题的时候看到有题解没有malloc 也没有new 直接int a[n],这种是不是编译器主动把它开到堆中了,如果不开在堆中,说不过道理啊?
C语言数组申请的问题
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
3条回答 默认 最新
- _GX_ 2022-03-17 04:21关注
变长数组是C99的新特性,它是在栈上分配的,下面是一个简单例子,用
clang
编译器在x64
架构上生成的代码进行解析。void f(int n) { int a[n]; a[0] = 1; a[1] = 2; } f: # @f push rbp ; 保存帧指针 mov rbp, rsp ; 当前帧指针 sub rsp, 32 ; 在栈上分配32个字节内存空间 mov dword ptr [rbp - 4], edi ; edi是函数传入的第一个参数,将其赋值给实参/局部变量n,*(rbp-4) = n mov eax, dword ptr [rbp - 4] ; eax = n mov ecx, eax ; ecx = n mov rax, rsp ; rax = rsp mov qword ptr [rbp - 16], rax ; 保存栈指针rsp到rbp-16,*(rbp-16) = rsp lea rdx, [4*rcx + 15] ; 接下来两个指令是计算在栈上分配VLA数组的内存大小,rdx=(sizeof(int)*n+15)/16*16,按16字节对齐 and rdx, -16 ; mov rax, rsp ; 计算rsp = rax = rsp - rdx,即在栈上分配内存,rax是VLA数组首地址 sub rax, rdx ; mov rsp, rax ; mov qword ptr [rbp - 24], rcx ; 保存数组长度n mov dword ptr [rax], 1 ; a[0] = 1 mov dword ptr [rax + 4], 2 ; a[1] = 2 mov rax, qword ptr [rbp - 16] ; rax = 原栈指针 mov rsp, rax ; 恢复栈指针,释放VLA数组内存 mov rsp, rbp ; 释放局部变量内存 pop rbp ; 恢复帧指针 ret ; 函数返回 . . . 4 +------------------+ | 调用函数帧指针rbp | 0 +------------------+ <---- 当前函数帧指针rbp | 实参n | -4 +------------------+ | | -8 +------------------+ | 保存的 | -12 + 栈指针rsp + | 占8个字节 | -16 +------------------+ | VLA数组 | -20 + 元素数目n + | 占8个字节 | -24 +------------------+ | | +------------------+ | | a[n-1] +------------------+ . . . +------------------+ | 2 | a[1] +------------------+ | 1 | a[0] +------------------+ <---- rsp, rax变长数组(VLA)首地址 . . .
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 1无用
悬赏问题
- ¥15 2020长安杯与连接网探
- ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
- ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
- ¥16 mybatis的代理对象无法通过@Autowired装填
- ¥15 可见光定位matlab仿真
- ¥15 arduino 四自由度机械臂
- ¥15 wordpress 产品图片 GIF 没法显示
- ¥15 求三国群英传pl国战时间的修改方法
- ¥15 matlab代码代写,需写出详细代码,代价私
- ¥15 ROS系统搭建请教(跨境电商用途)