C语言动态内存泄露常见问题内存分配改进方法详解
目录
- 一、例题
- 二、2种改进方法
- 法1:二级指针(传址调用)
- 法2:返回指针
- 总结
一、例题 试问该段代码能打印什么,或者不能打印什么,说出理由
#define _CRT_SECURE_NO_WARNINGS#include#include#includevoid getmemory(char*p){ p = (char*)malloc(100); }void test(){ char*str = NULL; getmemory(str); strcpy(str, "hello world"); printf("%s",str); }int main(){ test(); return 0; }
这段代码乍一看好像没有啥问题,test函数进去创建一个str嘛,然后str传给getmemory函数,开辟一块空间,然后hello world这字符串放进开辟的空间里,然后打印str也就是hello world嘛。
但是,上面的思路是完全错误的,代码完全无法运行,解释如下:
- 第一:你str传到getmemory函数里,p开辟一个空间,被开辟的空间和str没有关系
(传值调用和传址调用的区别)
- 第二:你getmemory函数出来之后,开辟的空间没有释放掉,而且你p由于函数的结束已经销毁了,p销毁之后再也无法找到开辟的空间,造成内存泄漏
也就是说p消失后,没办法再对开辟的空间进行释放,这时就会造成内存泄露
二、2种改进方法
法1:二级指针(传址调用)
代码如下(示例):
void getmemory(char**p){ *p = (char*)malloc(100); //p是str地址,*p是str}void test(){ char*str = NULL; getmemory(&str); strcpy(str, "hello world"); printf("%s",str); free(str); str = NULL; }int main(){ test(); return 0; }
因为之前的传值调用没法让p和str建立联系,那我们就传地址,开辟一块空间出来赋给*p
要注意的是,p是str地址嘛,*p也就是str,到这里,str掌握了新开辟空间的控制权。然后getmemory函数出来,进行strcpy和printf操作,最后不要忘记free掉原先的空间。
【C语言动态内存泄露常见问题内存分配改进方法详解】
法2:返回指针
代码如下(示例):
char* getmemory(char*p){ p = (char*)malloc(100); return p; }void test(){ char*str = NULL; str=getmemory(str); strcpy(str, "hello world"); printf("%s", str); free(str); str = NULL; }int main(){ test(); return 0; }
因为这里是开辟了一块空间给指针p管理嘛,str和p没有建立联系,那你直接函数返回p这个指针然后赋值给str即可,随后操作和方法1一样
总结 本文介绍了动态内存分配的常见例题及两种改进方法,读者需要理解为何会发生内存泄露和传值与传址调用的区别就可以熟练解决这类问题。以上,祝读者学习愉快~希望大家以后多多支持脚本之家!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 【生信技能树】R语言练习题|【生信技能树】R语言练习题 - 中级
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- C语言解方程的根和判断是否是闰年
- 动态组件与v-once指令
- C语言的版本比较