引言
上一篇笔记主要是介绍了内存的分布,那么如果看过我上一篇笔记的朋友,可能就已经接触过动态内存的使用方法:malloc、calloc、realloc函数来动态分配内存空间。那么这篇笔记主要是记载这三种函数使用方法。
malloc函数的使用:
举例分析:
举例:在堆内存中申请100个字节的内存空间,存入25个数据,并且使用一个函数f()专门负责这一块。使用tmp指针指向这块堆内存,然后再返回给main函数中的P指针。图解:
这里的地址信息:0x0123是一个举例
如果堆空间的地址是0x0123那么tmp指针就是0x0123并且返回给P指针。
代码的实现:
如果对第二步以及第四步的做法不懂的朋友,可以看我【C语言补充笔记5】了解数组的传递原理。
代码运行结果:
举一反三
- 如果使用完动态内存,并没有使用free()函数来释放内存,会导致什么结果?
答:会导致内存泄露!
操作系统可提供给所有进程的存储空间正在被某个进程榨干",最终结果是程序运行时间越长,占用存储空间越来越多,最终用尽全部存储空间,整个系统崩溃。
这个在产品研发中非常容易出现的问题,也是非常严重的问题,因此,为了将来工作减少失误,我们应该养成良好的习惯,使用完的内存空间一定要释放。
-
如果使用free()函数释放内存后,再次使用相同的地址访问内存空间,会出现什么现象?
答:结果不可预料。
第一种:非法行为,程序会崩溃。
第二种:如果内存空间未被再利用,则输出结果与之前一致,直至内存空间被再利用后。 -
如果使用free()函数释放自定义的指针可以吗?
答:不可以。因为malloc函数与free函数是配套使用的。free函数中的指针,必须是malloc中返回的指针。
calloc函数的使用:
calloc函数与malloc函数的区别:
void *calloc(size_t nelem, size_t elsize);
calloc在分配内存时,nelem作为指定对象数量(即需要多少块数据),elsize作为指定每个对象的大小,并且能够自动将数据初始化为零。
realloc函数的使用:
void *relloc(void *ptr,size_t size);
relloc函数主要用于重新分配内存空间。如果在之前分配的动态内存空间不够的时候,可以使用relloc函数对动态内存空间进行重新分配,而数据将会被搬到新的动态内存空间。
扩容空间可能遇到的问题:
- 扩容空间时,系统会尽量在“原地”扩建,这种情况很乐观。
- 扩容空间时,需要扩容的空间附近空间已被占用:
这种情况下,系统会将数据拷贝到另外一个足够大的空间,并且令指针指向新的地址。如图所示:系统将A空间的数据拷贝到C空间中
那么会照成的问题是:如果原来的A空间还有很多其他指针指向的话,扩容后的C空间,只有P指针拥有其地址,而其他指针则失效。
(例如:A朋友搬家了,地址也更换了,那么A的其他朋友并不知道其新家地址,那么久找不到A朋友了,只有当系统再次告诉其他朋友A的新家地址后,才能找到A)
代码实现: