面试典例——动态内存管理

来看一道“简单”却又“多坑”的面试题,关于动态内存的。?

1:找出下列代码的错误

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void GetMemory(char* p)
{
	p = (char*)malloc(100);
}
int main()
{
	char* str = NULL;
	GetMemory(str);                 
	strcpy(str, "hello world");
	printf(str);
	return 0;
}

这是一段十分简洁的代码,一提到动态内存,我们首先应该发现这两个明显的错误:

1.开辟动态内存后没有free掉;
2.在使用动态内存时没有判断返回值是否为空;


一般人稍稍一看也就这两个错误了,可是并不是这样的,最大的错误是
GetMemory()函数的形参p是一个拷贝值,所以开辟的内存起始地址并没有返回到str上,导致str一直为NULL,当GetMemory函数一结束,里面的局部变量p就会被释放掉导致无法再找到开辟动态内存的地址,从而导致内存泄漏;

这里修改后的代码为:

void GetMemory(char** p)
{
	*p = (char*)malloc(100);
}
int main()
{
	char* str = NULL;
	GetMemory(&str);                 
	strcpy(str, "hello world");
	printf(str);
	free(str);
	return 0;
}

这里我们将函数参数改为一个二级指针,实参则为一个指针的地址,这样拷贝的二级指针p也指向str,解引用后则就是str;
画一张图来更好地理解一下:

 

 这里还有一种方式更改错误,这种方式就是设置一个返回值,这样更加易懂:
 

char* GetMemory(char* p)
{
	p = (char*)malloc(100);
	return p;
}

int main()
{
	char* str = NULL;
	str = GetMemory(str);                 
	strcpy(str, "hello world");
	printf(str);
	free(str);
	return 0;
}

 

2.找出下列代码错误:

#include<stdio.h>
#include<stdlib.h>

char* getmemory(void)
{
	char arr[] = "i love you";
	return arr;
}
int main()
{
	char* p = getmemory();
	printf("%s\n", p);
	return 0;
}

这个题估计很多人看了之后觉得没有啥问题,但我们运行结果将会是一堆乱码;
因为在函数结束后,它的栈帧就会被释放但这个数组arr的数据都还残留在内存中,只是不能被引用,而此时我们又调用了printf函数,就会产生新的函数栈帧,这个函数栈帧就会覆盖掉getmemory函数的栈帧,所以再用指针寻找原来的arr时,原有数据已经被覆盖了,所以是一团乱码。

我们可以调试(F10)来查看证明我们的观点,将箭头运行到printf函数处,我们查看*p,将会看到它的值还是i,而将指针指向return时,*p的值已经不是原来的值了。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值