malloc与free

关于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);
}

虽然以二级指针回传,有些难理解,但是在后面的深入学习中我相信这一点会用到很多的,所以理解不了,强记要记下哦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值