文章标题
来源:互联网 发布:windows phone微信 编辑:程序博客网 时间:2024/06/01 22:18
关于C中的malloc和free的相关想法和实验##
本人刚入们数据结构这块,遇到不少关于内存管理这块的问题,做了一些实验,不是很确定,暂将这些想法和结果记录在这里,有误的地方大家勿喷,和大家一起讨讨论就好(哈哈哈),希望自己不断进步#__#malloc函数可以从堆给分配一整块的存储空间,并返回这个片的首地址(void *),一般需要强制转化。如char* str = (char *)malloc(10*sizeof(char));free函数是与malloc对应的函数,用于释放某个指针指向的空间区域,这片空间区域一定要通过malloc函数来分配。如接上free(str);
此时,原先str指向的空间被释放,从而可以成为下一次malloc的选取对象(我认为不能被malloc用于分配的这块内存是已经被占用(要是到结尾都没被释放,就是内存泄漏)),释放后,最好将str置空,因为释放并不影响str,会成为野指针,其内容是不确定的,要是再free一次将会崩溃。
实验:
typedef struct{ char *name;}PERSON,*PERSON_T;void free1(PERSON* per){ free(per);}void free2(PERSON* per){ free((*per).name); (*per).name = NULL;}int main(){ PERSON person; person.name = (char*)malloc(5); memset(person.name,0,5); memcpy(person.name,"yyb",strlen("yyb")); printf("原始的串:%s\n",person.name);//显示yyb free1(&person); printf("释放错误的指针:%s\n",person.name);//显示yyb free2(&person); printf("释放正确的指针:%s\n",person.name);//显示null}
产生上面的结果是因为free1(&person)函数释放一个不是malloc返回的指针,从main中看person相当是一个普通变量(内存是栈里的),没有实际释放name指针,所以仍然会显示yyb。
实验进阶:
typedef struct{ void* data;}STU,*STU_T;typedef struct{ char *name;}PERSON,*PERSON_T;void test(void * data){ STU_T stu = (STU_T)malloc(sizeof(STU)); stu->data = data; free((PERSON_T)stu->data); free(stu);}void my_free(PERSON_T per){ free(per->name);}int main(){ PERSON person; person.name = (char*)malloc(5); memset(person.name,0,5); memcpy(person.name,"yyb",strlen("yyb")); printf("原始的串:%s\n",person.name); test(&person); printf("\n%s\n",person.name);}
1:运行上面的代码会发现main中任然会显示yyb,原因还是因为test中 free((PERSON_T)stu->data);free(stu);
都没有实际释放到name.
将test修改后
void test(void * data){ STU_T stu = (STU_T)malloc(sizeof(STU)); stu->data = data; free(((PERSON_T)(stu->data))->name); free(stu);}
这次main不显示yyb,说明真的释放了;
3:为了和在哪malloc,就在哪释放结合起来,现在需要把test的data指针回传给main函数,这里不考虑以返回值的形式,而是以参数传递的形式。主要改动了test和main
void test(void * data,void** value){ STU_T stu = (STU_T)malloc(sizeof(STU)); stu->data = data; *value = stu->data; free(stu);}int main(){ PERSON person; PERSON_T value = NULL;//用于接收回传指针 person.name = (char*)malloc(5); memset(person.name,0,5); memcpy(person.name,"yyb",strlen("yyb")); printf("原始的串:%s\n",person.name); printf("\n*****开始新的实验*******\n"); test(&person,(void**)&value); free(value->name); printf("\n%s\n",person.name);}
这里有个疑问:为什么要用二级指针?以往都是通过传递一个一级指针给被调用函数,然后再被调用改变这个内容即可,但这里不同的是回传一个指针,设A是一级指针,*A= 一个指针通不过编译,是不被允许的,再者二级指针一种理解就可以理解为保存地址。
此外,还想附上其他一个例子:
void GetStr(char * s){ s=(char *)malloc(10*sizzeof(char)); memset(s,0,10); memcpy(s,"i is not str",strlen("i is not str"));}int main(){ char* str = NULL; GetStr(str); printf("%s",str);}
结果并不是i is not str,因为s是str的一个副本,一开始都是NULL,但是s经过malloc后就直到别处了,而str任然指向NULL;
修改:
char* GetStr(char * s){ s=(char *)malloc(10*sizzeof(char)); memset(s,0,10); memcpy(s,"i is not str",strlen("i is not str")); return s;}
在main中将GetStr(str)改为str =GetStr(str)即可;
或者通过将s以参数的形式回传回来,修改如下:
void GetStr(void** s){ *s = (char*)malloc(10*sizeof(char)); memset(*s,0,10); memcpy(*s,"i is not str",strlen("i is not str"));}int main(){ char* str = NULL; GetStr(&str); printf("%s\n",str);}
虽然以二级指针回传,有些难理解,但是在后面的深入学习中我相信这一点会用到很多的,所以理解不了,强记要记下哦
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- easyui的tree 控件设置checkbox单选设置
- 数据结构实验之图论一:基于邻接矩阵的广度优先搜索遍历
- leetcode 122-Best Time to Buy and Sell Stock II
- 搭建nginx rtmp流媒体服务器(超详细)
- STL应用-——懒省事的小明
- 文章标题
- vscode: Visual Studio Code 常用快捷键
- 实现容器的底层技术
- Linux下切换python2和python3
- C++ 结构体可以直接赋值
- Python基础4
- AspectJ实现AOP(xml配置方式)
- DruidDataSource的参考配置
- Ubuntu下安装软件提示软件包 apport 需要重新安装解决方法