介绍C语言中堆上内存分配和栈上变量的区别,以及如何使用malloc和calloc在堆上分配内存。
工具/原料
C
VisualStudio
方法/步骤
1、首先,我们在堆裼沙钔炯上分配内存有两个常用函数,malloc和calloc.它们功能类似。void*malloc(unsi爿讥旌护gnedintsize)传入的size数值就是要分配的字节数,返回分配的内存块首指针。calloc就是把两个参数乘起来作为分配字节数。
2、我们看如下代码。使用malloc分配的数组看起来和直接声明的数组类似,一样可以通过下标访问和使用。但是,a和b有着本质不同,一个在栈上,一个在堆上。
3、我们看到,关于a和关于b的汇编有很大不同,无论是声明还是访问。
4、我们士候眨塄大致查看汇编代码,可以看到inta[10]其实不对应任何汇编。这句话只是告知编译器,在栈上预定10个int的空间好吧a[0]a[1]..缕计瓤账.映射到栈上。a的地址并不存储在堆或栈上,而是被写进了汇编码的操作数。而malloc函数的调用,就有实际代码执行了,并且把堆上地址存入b.b则是栈上一个变量。
5、对a[0]和a[6]的赋值代码如图,可见完成一个栈上墙绅褡孛数组元素赋值需要三条语句:调入一个int的字号俗劭蜾节数4,计算与a[0]的地址偏移,根据栈底指针ebp算出编译器决定的a[0]位置ebp+2Ch,然后在加上偏移得到a[i]的位置并操作。
6、对b[0]和b[6]的赋值代码如图,可见完成堆上数组元素赋值需要四条语句:调入一个int的字节数4,计算与b[0]的地址偏移,从栈上的指针变量b获得堆上b[0]的地址,根据b[0]算出b[i]在堆上的位置并操作。
7、通过下图对比,更能明显说明问题,使用malloc函数,栈上的变量b持有堆上b[0]所在的地址。而直接声明变量inta[10],则a不存在,a[0]是一个地址常量,由编译器写进汇编。