C语言动态内存管理笔试题

动态内存管理笔试题

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

程序运行结果:没有输出,奔溃

解释:str传递给GetMemory函数是值传递方式,所以GetMemory函数参数p是str的一份临时拷贝;在GetMemory函数内部动态申请的空间,首地址赋给了参数p指针,因为形参的生命周期跟局部变量一样,出了函数便自动销毁,所以GetMemory函数返回之后,指针p便销毁,使得动态开辟的100个字节的内存存在内存泄漏,无法释放;同时外部的str因为是值传递,所以并没有改变,依然是NULL,strcpy把“hello world”拷贝到空指针中,明显出错,print(str)也出错。

正确修改1:

char* GetMemory(char* p)	//函数返回类型改为char*
{
	p = (char*)malloc(100);
	return p;				//将p指针返回
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory(str);		//用str指针接收返回值,这样str指针就指向了动态开辟的100个字节的空间
	strcpy(str, "hello world");
	printf(str);	/*该打印方式没问题,printf("hello world")只是把字符串的首地址即'h'的地址传给printf函数,便可以进行打					印,同理,str指向的也是'h'的地址,所以可以打印*/
	free(str);		//最后释放动态开辟的空间
}

正确修改2:

void GetMemory(char** p)		//参数改为二级指针
{
	*p = (char*)malloc(100);	//参数p存放的是str的地址,*p便得到str,即用str指向malloc开辟的空间
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str);		//要想改变变量的值,就要传地址过去
	strcpy(str, "hello world");
	printf(str);
	free(str);
}

char* GetMemory (void)
{
	char p[] = "hello world";
	return p;
)
void Test (void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
int main()
{
	Test();
	return 0;
}

程序运行结果:烫烫烫烫烫烫烫烫(乱码)

解释:因为在GetMemory函数内开辟了一块连续的空间,用来存放字符串,数组名指向“hello world”字符串的首地址,return p时返回的的确是指向该字符串所在空间的首地址,但该空间因为是在栈上开辟的,所以函数结束时该空间就被释放了,还回给了操作系统,当指针str接收到该地址时==(因为地址其实就是个标签,门牌号,不是什么变量,所以函数结束也可以返回)==,地址里存放的内容可能已经被系统给更改了,不再是字符串,也可以说是一块未知的内存空间,所以打印出来的是乱码。

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

程序运行结果:world

考查点:free函数不会自动将指针置空

解释:虽然程序能运行,也有结果出来,但代码已经出现了非法访问内存的错误;在动态申请完空间后,并没有对str指针进行判空操作,这也是一个小错误,不够严谨;strcpy函数完成操作后,内存放入了“hello”字符串,随后free(str),释放掉了刚刚动态开辟的100个字节的内存空间,还回给了操作系统,但指针并没有置空,所以依然指向着刚才的空间,if判断为真,再次往这块空间拷贝“world”字符串,此时已经对内存进行了非法访问,最后输出该空间内容。

正确修改:

void Test (void)
{
	char* str = (char* ) malloc (100);
    if(str == NULL)					//对动态内存是否申请成功进行判断
    {
        printf("申请动态内存失败\n");
        return;
    }
	strcpy(str,"hello");
    free (str) ;
    str == NULL;			//手动将指针置空,防止后续操作对非用户空间进行访问和操作
	if (str != NULL)
    {
		strcpy(str, "world" );
		printf(str) ;
    }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值