一、堆空间的申请与释放。
1、堆空间的特点。
堆区不像栈区一样,通过申请变量而得到,而是通过写代码调用malloc()函数而得到。
代码中定义局部变量 -> 等价于在栈区申请空间。
代码中定义全局变量 -> 等价于在bss/data区申请空间。
代码中出现了常量"hello" -> 等价于在rodata区申请空间。
代表中调用malloc函数 -> 等价于在堆区申请。
2、如何申请堆空间?如何释放释放空间?
堆空间必须主动申请,主动释放,也就是说在函数中申请了栈区和堆区的空间,在函数返回时,只有栈区的空间会自动释放,堆区空间是不会释放,除非你主动释放。
1)申请空间。 -> malloc() -> 查看用法: man 3 malloc
函数功能: allocate dynamic memory
//申请堆空间
使用格式:
头文件: #include <stdlib.h>
原型:void *malloc(size_t size);
参数:
size: 需要申请的堆空间的总字节数
返回值:
成功: a pointer to the allocated memory. -> 堆空间的地址 (void *)
失败: NULL (NULL = malloc(0))
注意:
这个堆区的空间申请下来后,因为系统不知道你申请的空间是来放什么数据的,所以地址的类型是void *,我们用户使用堆区空间,就必须先强制转换类型。
2)主动释放。 -> free() -> man 3 free
函数功能: free dynamic memory
//释放堆空间
使用格式:
头文件: #include <stdlib.h>
原型: void free(void *ptr);
参数:
ptr: 需要释放的空间的地址。(其实就是malloc函数的返回值)
返回值:无。
例题: 申请一块堆空间,用于存放一个整型数据,赋值一个100给这片内存空间,然后释放该该空间。
#include <stdlib.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
int *p = (int*)malloc(4);
*p = 100;
printf("%d\n",p[0]); //p[0] = *(p+0) = *p
free(p);
return 0;
}
结果:100
练习1: 申请了堆空间后,初始值是多少? -> 0
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int *p = (int *)malloc(sizeof(int)*3);
printf("p[0] = %d\n",p[0]);
printf("p[1] = %d\n",p[1]);
printf("p[2] = %d\n",p[2]);
free(p);
return 0;
}
练习2: 在一个自定义函数中申请堆空间,看看函数返回之后,这个堆空间还在不在。
#include <stdio.h>
#include <stdlib.h>
int *fun(int x) //自定义函数
{
int *p = (int *)malloc(4);
p[0] = x;
return p;
}
int main(int argc,char *argv[])
{
int data = 100;
int *p = fun(data); //p依然指向这片内存,这片内存由于是堆,所以没有释放。
printf("p[0] = %d\n",p[0]); //100
free(p); -> 当你使用完堆之后,就要主动释放。
return 0;
}
练习3: 堆空间释放后,还可以使用吗?如果使用会怎么样? -> 可以,但是有可能就不是之前的那些值。
#include <stdio.h>
#include <stdlib.h>
int *fun(int x) //自定义函数
{
int *p = (int *)mall