内存的区域
在计算机中,内存可以被粗略的划分成,代码段、数据段、堆区以及栈区,
如下图所示
栈区一般用于存放代码中定义的生命周期较短的局部变量,而堆区则是内存管理函数所开辟内存的对象
内存动态管理函数
- malloc
- calloc
- realloc
- free
malloc
malloc函数可以申请一块连续的内存空间
1 | void* malloc(size_t size); |
它的参数类型是一个无符号整型,返回一个void * 类型的指针,参数size代表申请字节数,如果申请空间过大,或没有足够的空间,就可能会申请失败,申请失败时返回NULL。
理论上来讲,在使用malloc函数时,应该需要判断返回值是否为NULL,如果是,则程序退出。
由malloc申请的内存,必须释放,否则就会出现“内存泄漏”的情况。
如果程序中反复使用malloc而没有释放,那么就会导致系统内存下一直被申请,而没有被释放,内存越来越少,最终就会内存不足。
malloc函数申请的内存会一直持续存在到程序结束(生命周期长,跟随整个程序),除非显示使用free来进行释放。
calloc
calloc函数和malloc函数用法类似,功能也类似,最大的区别是calloc在申请到内存空间之后,会将其初始化为全0,而malloc则不会对内存进行初始化
realloc
realloc函数的功能是对已申请到的内存空间进行扩容
1 | void* realloc(void* ptr , size_t size); |
realloc的参数分别是一个指向内存空间首地址的指针和一个数值为扩容后字节数大小的无符整型,如果当前的内存空间不足以容纳扩容后的大小,那么realloc会自动找到一块足以容纳扩容后大小的连续内存空间,将原内存中内容拷贝过去,再释放原内存空间,所以返回值和参数不一定相等!
free
释放当前内存空间,它的参数是一个指向由malloc等函数开辟的内存空间的首地址的指针。
内存泄露
内存泄漏是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
- 判断是否存在内存泄漏可以通过稳定性测试来进行,让被测试逻辑重复执行几十万次,记录开始运行时占用的内存数,再记录结束时占用的内存数。
- 如果程序中存在内存泄漏,可以使用一些内存泄漏检测工具,或者根据以往经验推测,也可以通过二分法查找问题
在使用malloc等内存管理函数时,务必记得使用free函数释放掉所申请的内存,即使有的程序不需要释放内存或者不释放内存也不会造成内存泄漏。我们需要养成良好的习惯,这样能大大减少问题发生的概率。