数据结构malloc、free使用

数据结构malloc、free的使用

malloc函数

函数原型

#include
void *malloc(unsigned long size);

头文件: malloc是一个系统函数,调用它的时候必须包含头文件

功能: 在堆中开辟一块指定大小的空间,申请内存的动态存储空间即堆中分配一个长度为size的连续空间。

返回值: 函数的返回值是一个指向分配内存起始地址的指针,类型为void* 型(表示未确定的类型指针,C、C++规定void*类可以强制转换为任何其他类型的指针)。(即malloc函数返回的是一个地址,而这个地址是动态分配的内存空间的起始地址)。如果此函数未能成功地执行,例如遇到空间不足的情况,就会返回空指针NULL。
注意: 当内存不再使用时,应使用free()函数将内存块释放

②与new的区别
new返回指定类型的指针,并且可以自动计算所需要的内存大小;而malloc必须由我们自己计算字节数,并且在返回后强行转换为实际类型的指针

int *p;
p= new int;//返回类型为int*类型(整型指针),分配大小为sizeof(int)
int *shi;
shi =new int[100];//返回类型为int*类型(整型指针),分配大小为sizeof(int)*100

关键的典型用法来了!!!

int *p;//定义一个整型指针变量p
p = (int*)malloc(sizeof(int)*10);
//分配10个整型存储单元
//将这10个连续的整型存储单元的  首地址 存储到指针变量p中 
float *p;//定义一个浮点型指针变量p
p = (float*)malloc(sizeof(float)*10);
//分配10个浮点型存储单元
//并将这10个连续的浮点型存储单元的  首地址  存储到指针变量p中

Q:为什么要在malloc函数前面加(数据类型*)
malloc函数返回的是void*类型(即未确定的指针类型),若用C++写成

int *p;
p = malloc(sizeof(int));

在这里程序无法通过编译,会报错:“不能将void* 赋值给int* 类型变量”,所以必须在malloc函数前加(int*)来强制转换

Q:函数实参为什么是sizeof(int)?
用于指明一个整型数据需要的大小,如果写成:

int *p=(int*)malloc(1);

这里也能通过编译,但只分配了1个字节大小的内存空间,当存入一个整型数据进去时(整型占4个字节),可能会导致后面的内存原有的数据内容被修改。

③关于静态内存
int a=2;这里表示分配了4个字节的静态内存。这里强调静态内存和静态变量是没有任何关系的,静态变量的关键字是static
③判断一个内存是静态内存还是动态内存,凡是动态分配的内存都有一个标志,都是用一个系统的动态内存函数来实现的,如malloc或者calloc
使用malloc动态分配内存

int *p=(int*)malloc(4);

这里的作用:
①请求系统分配4字节的内存空间,并返回第一字节的地址,然后赋给指针变量p。注意在这里,指针变量是静态分配的。因为动态分配的内存都有一个标志,即用一个系统的动态分配函数实现,而指针变量是传统方式定义的,所以是静态分配的内存空间,而p所指向的内存是动态分配的。

free函数

函数原型: free(p);//p为指针

头文件: #include 或者 #include

功能: 能够在释放在堆中开辟的内存空间,传入一个任意类型的指针变量,指向被释放区域的首地址,被释放的区域是malloc开辟的空间。

实现原理: 操作系统在调用malloc函数时,会默认在malloc分配的物理内存前面分配一个数据结构,这个数据结构记录了这次分配内存的大小。当我们需要free的时候,free函数会把指针退回到这个结构体中,找到该内存的大小,这样就能释放内存了

注意:
①free释放内存空间只是失去了对地址的操作权限,将参数指针指向的内存归还给操作系统,并不会把参数指针置NULL。并没有保证清理内存空间,即不是真正意义上的释放内存
②free()函数释放的是指针指向的内存而不是指针。指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在的,只是指针指向的内容的垃圾,是未定义的。
③在释放内存空间之前需要添加判断,释放后及时将p赋值为NULL,避免多次释放同一内存空间

free(p);
p=NULL;

后面学习了堆与栈还有链表时会补充内容…未完待续

你可能感兴趣的:(数据结构与算法)