C语言中malloc是动态内存分配函数。
函数原型:void malloc(unsigned int num_bytes);
参数:num_bytes 是无符号整型,用于表示分配的字节数。
返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。void 表示未确定类型的指针,void 可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者…)
功能:分配长度为num_bytes字节的内存块
注意:当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。关于该函数的原型,在以前malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。
实例:
#include"stdio.h"
#include"malloc.h"//malloc()函数被包含在malloc.h里面
int main(void)
{
chara=NULL;//声明一个指向a的char类型的指针
a=(char)malloc(100*sizeof(char));//使用malloc分配内存的首地址,然后赋值给a
if(!a)//如果malloc失败,可以得到一些log
{
perror(“malloc”);
return-1;
}
sprintf(a,"%s",“HelloWorld\n”);//“HelloWorld\n"写入a指向的地址
printf(”%s\n",a);//输出用户输入的数据
free(a);//释放掉使用的内存地址
return0;//例2有无内存泄露?
}
(分配类型 *)malloc(分配元素个数 *sizeof(分配类型))
如果成功,则返回该空间首地址,该空间没有初始化,如果失败,则返回0
,动态分配内存时的返回值是不确定的,也就是说我们在申请空间的时候,还不知道用户用这个空间来存储什么数据类型,所以使用voId,没有外地表示的,是申请空间的首地址,如果我们申请的是200个空间,我们返回的只是200,而不是200到203.我们以整形为例占用4个字节,
注意:我们在进行开辟存储空间的时候,一般都是给予一个特定的数值,而是用你所需要开辟空间的个数去乘以每一个类型所占据的字节数,这样对于不同的操作系统,我们也能够控制我们需要的空间数量
函数值是所分配区域的第1个字节的地址,或者说,此函数是一个指针型函数返回的指针指向该分配率的开头位置,注意安全措施,不是返回的直接地址的长度,而是第1个字节的地址,同时呢函数也可以看成是一个指针型函数,对于指针型函数一定会有返回值,而此函数返回的指针指向该分配率的开头位置,
Elem是所有数据类型的总称,把具体的事情出现后就有了概括性,当我们不是知道用户具体想要开辟什么样的类型的空间地址,我们可以使用抽象数据类型Elem,
注意指针的及类型为voId及不指向任何类型的数据,只提供一个地址,没有快递,也就是说明不知道用户需要开辟什么样数据类型的空间,同时也不知道返回的数据类型是什么样的,如果死了,他说不能正常执行就说明硬件内存没有足够的空间来供用户进行使用,属于硬件层面的技能,
同时我们要知道与calloc函数的区别是什么样子:
Calloc,它的作用是在内存的动态存储空间中分配三个长度为30的内连续空间,这个空间是比较大的,足以保存一个数字,但是他的参数是有两个的,而我们前面所提到的,另一个函数它的参数只有一个,
3.接下来我们来了解free函数,他的函数原型为void free (void *p);这里我们需要注意的是,第1个参数是申请时的空间,这里申请就是指malloc函数进行申请得到的地址值,第2个参数是指扩充之后的地址,空间大小的数值,比如说我们原来申请的空间是10个,那么我们可以在要5个空间,这里我们就需要写第2个参数的值为15而不是5,他是针对于colloc函数获取动态空间以及malloc函数,获取空间得到的空间大小,这里就相当于是一开始,我们没有想想充分到底需要多少个空间,但是随着数据的进行,我们知道自己所需要的空间是大了或者是小了,那么我们对我们所需要的空间进行一个改动,挑类似鱼,我们吃馒头,一开始我们打算的是吃三个馒头,但当吃了两个馒头之后,我们觉得自己已经好了,那我们就需要将自己跟前的馒头数量改变一下,改为2,也就是减少一个,当吃完两个感觉剩下的还是不够吃,就需要再向空间{食堂的大师傅}申请两个馒头,这里申请两个馒头,但是不能写2,而是需要写5,这里就涉及到两个问题,我们向食堂的大师傅去要两个馒头,如果食堂里是有两个馒头,那么我们就是申请成功了,如果食堂里没有,那么我们就会申请失败,返回值就是空,也就是null,没有空间了,而对于我们将自己跟前的馒头拿回食堂就不存在返回时不接收我们的馒头的情况,realloc(p,50);指的就是将p所指向的已进行分配了的动态空间改为50个字节啊,
下面我们将详细的了解一下realloc函数,也就是作用机制,第1种情况,比如我们一开始申请了10个空间,当我们使用到第10个的时候,发现我们还需要5个空间才能完成我们这次的存储任务,那么我们就需要再开辟5个空间,使用函数realloc函数,传递参数为15,我们发现,原来的地址空间当中,后面有5个连续的空间与前面的10个空间是相连的,那么我们就一次性的将15个空间再分配给原来的地质空间,变成15个空间,此时分配完成,第2种情况,当我们想要开辟15个联系的空间时,发现其中的某个空间是被其他元素所占据式,那么我们就无法成功开辟这15个空间的内存,这也是由于我们在申请动态内存空间时,必须申请的是连续的动态空间,如果我们没有联系的15个空间的话,那么我们就放弃原来的可以存储10个空间大小的仓库,然后去寻找另外一个仓库,我们所需要成长的另一个仓库的大小是15个空间,然后呢,我们需要将原来仓库的物品搬到我们的新仓库当中进行存储,
我们可以简单的进行类比,比如我们成立了一家公司,这家公司的规模是10个吊车的仓库,那么我们就需要去寻找大小为10的仓库来进行存储,当我们有了更雄厚的实力,将原来的10个吊车改为20个车,那么我们就需要去另外找一个仓库来存储这20个车,并且我们需要到原来的仓库归还给我们一开始租赁的那一个人,并且把所有的车放到我们新开辟的车间进行存储,方便我们进行同意的管理,我们是不能够将所有的车存放到一个空间当中的,是不符合我们的计算机硬件系统的
free是针对于前面的两个函数进行实现功能的,我们需要传递的参数就是一个地址值,为啥呢?因为我们知道前面两个函数返回的都是一个地址值,也就是可以理解为我们想使用一个仓库,那么我们只需要把他的钥匙拿过来就可以了,还可以理解成我们想喝一瓶酒,那么我们必须拿起瓶器,,想开一辆车,那么我们需要钥匙,而不是搬走整个车,但是我们类比前面的函数,可知Free函数它不需要返回值类型,而且他也不研究他是否成功,就像我们去借一辆自行车来骑,那么我们使用了这个自行车,我们返回去肯定就是会成功的,而不是返回失败,
4.realloc函数:函数原型void realloc(voidp,UnsIgned.Intsize.)
1.单链表进行逆序存储的原理理解:
我们说为什么提到逆序存储这一词语?因为我们正序存储时,需要寻找最后一个位置,来进行结点的插入操作,这时候就浪费了时间和空间,找最后一个节点的位置时有两种方法,一个是指针的方法,一个是循环的方法,为了避免这两种方法,我们提出了逆序存储的原理,也就是说我们把插入节点的位置进行固定,每次插入从首源节点的位置进行插入,注意此时我们插入的是一个具有头节点的单链表,此时单链表是空的,
顺序存储结构和链表存储结构在时间复杂度上有什么区别?
下面讨论如何将两个有序链表合并成一个有序链表
此处的两个游戏列表指的是他们的顺序是从大到小,或者是从小到大的事情,也就是说他们的排列是很规则的,