【原创】浅谈指针(十一)alloca函数
前言
好几天没写了,最近网课,事情也比较多,今天多写点东西。
目录
- 前言
- alloca函数
- 1.简介
- 2.反汇编看alloca
- 3.手工调用alloca函数
- 4.注意事项
alloca函数 1.简介 之前看《30天自制操作系统》的时候,看见了这样一个东西:
文章图片
没错,这就是alloca函数。
2.反汇编看alloca 现在,我们把VS打开,看看反汇编是如何的:
(顺便说一下反汇编的方法,就是下两个断点,如图)
文章图片
然后左上角就会出现反汇编的页面,点进去
文章图片
代码如下:
#include "stdafx.h"
#include
#include
#define N 100
int main(){
char a[N];
for(int i=1;
i<=N;
i++){
a[i]=0;
}
}
【【原创】浅谈指针(十一)alloca函数】反汇编的结果是:
pushebp
004D1381 8B ECmovebp,esp
004D1383 81 EC 3C 01 00 00subesp,13Ch
004D1389 53pushebx
004D138A 56pushesi
004D138B 57pushedi
004D138C 8D BD C4 FE FF FFleaedi,[ebp-13Ch]
004D1392 B9 4F 00 00 00movecx,4Fh
004D1397 B8 CC CC CC CCmoveax,0CCCCCCCCh
004D139C F3 ABrep stosdword ptr es:[edi]
004D139E A1 00 70 4D 00moveax,dword ptr [___security_cookie (4D7000h)]
004D13A3 33 C5xoreax,ebp
004D13A5 89 45 FCmovdword ptr [ebp-4],eax
似乎看不出什么名堂来,但是如果一旦我们把N改为更大的数字,例如100000,再来看看:
00FF1380 55pushebp
00FF1381 8B ECmovebp,esp
00FF1383 B8 78 87 01 00moveax,18778h
00FF1388 E8 30 FE FF FFcall@ILT+440(__alloca_probe) (0FF11BDh)
00FF138D 53pushebx
00FF138E 56pushesi
00FF138F 57pushedi
00FF1390 8D BD 88 78 FE FFleaedi,[ebp-18778h]
00FF1396 B9 DE 61 00 00movecx,61DEh
00FF139B B8 CC CC CC CCmoveax,0CCCCCCCCh
00FF13A0 F3 ABrep stosdword ptr es:[edi]
00FF13A2 A1 00 70 FF 00moveax,dword ptr [___security_cookie (0FF7000h)]
00FF13A7 33 C5xoreax,ebp
00FF13A9 89 45 FCmovdword ptr [ebp-4],eax
看第四行,有一个叫做
call @ILT+440(__alloca_probe)
的一个东西,汇编语言中,call指令后面跟的东西是一个函数,那么alloca_probe就是那个在栈中分配内存所使用到的函数。
我们由此得知,在栈中分配超过某个特定值的内存,就需要调用alloca函数。
(文章开头那本《30天自制操作系统》书中写的是4KB,但是我这里测试下来,似乎又不是4KB,这里暂时存疑)
3.手工调用alloca函数 我们这里尝试运行如下的代码:
#include "stdafx.h"
#include
#includeint a;
int main(){
int b;
int *p=(int*)alloca(sizeof(int));
printf("%p %p %p ",&a,&b,p);
system("pause");
}
可以看出,输出的p的地址与b的地址更加相近。b写在main函数中,说明这是一个局部变量,或者叫做自动变量,它是保存在栈中的。由此,我们得知,alloca也是会分配在栈中。
4.注意事项 (1)alloca所分配的内存会被自动释放,不能free!!!
如果我们尝试使用free释放p的内存,在VS中,引发了一个运行错误。
文章图片
(2)alloca的可移植性不高,因此我们一般不使用它。
在调用alloca()的函数返回的时候,它分配的内存会自动释放。也就是说,用alloca()分配的内存在某种程度上局部于函数的堆栈帧或上下文中。
alloca()不具可移植性,而且在没有传统堆栈的机器上很难实现。当它的返回值直接传入另一个函数时会带来问题, 如 fgets(alloca(100), 100, stdin)。
(3)由于C99开始引入了可变长数组VLA,可以使用这个功能来更好地完成alloca所需要的完成的任务。
推荐阅读
- CPSC 319图数结构
- Linux内核添加系统调用
- python|python淘宝关键字词云分析
- Pygame实战|【Pygame实战】众志成城 同心战“疫”,为抗疫加油,只待春暖花开(附抗疫小游戏)
- Turtle|【Turtle系列】2022年春天限定(“樱你而来”带着喜欢的人一起去看一场粉色浪潮吧~)
- Python|【Turtle系列】端正心态正确面对疫情,守护安全防线不放松,共抗疫情,只待春来~
- 图像处理|【OpenCv】图像分割——分水岭算法
- 与君共勉|【数据结构与算法】最小生成树与最短路径问题
- Python|【Opencv实战】这是我见过的最强大“美颜滤镜”,代码美颜傻瓜式一键操作~(附源码)
- 图像处理|【OpenCv】图像分割——聚类算法