【一文搞定一问题】动态内存管理中的四道经典笔试题

在学习了动态内存开辟之后,下面给4道经典的动态内存管理相关的笔试题,一起来练练手吧!

【一文搞定一问题】动态内存管理中的四道经典笔试题

题目一

运行下面的程序,会出现什么结果?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
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;
}

解答:程序会崩溃。

  1. 传参时进行的是值传递,并且函数GetMemory并没有返回值,所以函数中p的地址并没有被带回到str中,str始终是NULL,所以当用字符串拷贝对str进行操作时,程序就会崩溃,因为NULL指针指向的空间是不能直接访问的。
  2. 函数GetMemory中开辟的动态内存没有释放,会造成内存泄漏。

改进:

  1. 让GetMemory函数把开辟的空间的地址带回来(可以采用传址调用,也可以让函数以返回值的形式把地址带回去)
  2. 动态开辟的空间在使用完后用free释放

改法1:

void GetMemory(char** p)
{
	*p = (char*)malloc(100);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str);//址传递
	strcpy(str, "hello world");
	printf(str);
	free(str);//使用完毕,释放内存
	str = NULL;//并将str置为NULL
}
int main()
{
	Test();
	return 0;
}

改法2:

char* GetMemory(char* p)
{
	p = (char*)malloc(100);
	return p;//利用返回值把开辟的空间的地址传回去
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
	free(str);//释放空间
	str = NULL;
}
int main()
{
	Test();
	return 0;
}

题目二

运行下面的程序,会出现什么结果?

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中的数组p是在栈空间中开辟的,数组出了函数之后就被销毁了,但是数组的起始地址却被返回给了str。当str拿到地址的时候,它所指向的那块空间已经还给内存了,之后这块空间里面会放什么内容我们并不知道,当用printf对str指向的空间中的内容进行打印时,会打印随机值。

程序打印结果如下:
在这里插入图片描述

题目三

运行下面的程序,会出现什么结果?

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

解答:程序会在屏幕上打印hello,但是程序没有释放内存,造成内存泄漏了。

改进:在使用完动态开辟的内存之后,要用free释放内存。

void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
	free(str);//释放空间
	str = NULL;
}
int main()
{
	Test();
	return 0;
}

题目四

下面的代码存在什么问题?

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;
}

解答:程序对野指针进行了非法访问。
程序在free了str之后,str指向的空间已经还给操作系统了,但是程序并没有把str置为NULL,此时的str是野指针,当strcpy想把world拷贝给str时,就造成了非法访问。

改进:
在free之后把str置为NULL。

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

上面的四道题你是不是都答对了呢?

给棒棒的自己点个赞!

在这里插入图片描述

同时也记得给文章点个一键三连哦~

也欢迎你在评论区和我进行交流!

关注我,一起精进C语言~
在这里插入图片描述

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值