动态内存经典笔试题分析

题目1:

大家可以先看看这段代码有没有什么问题:

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

如图:有两个警告,要是不顾及这些警告强制运行,就会使系统崩溃。
在这里插入图片描述

在这里插入图片描述
我画了个图简单分析一下原因:(这里假设起始地址是0x11223344)
在这里插入图片描述
这段代码由main函数调用Test函数。
Test里面的运行步骤:

  1. 创建一个指针变量赋值NULL
  2. 将str也就是NULL传参给GetMemory
  3. 用p指针接收过来的NULL
  4. 创建空间并将起始地址传给p,这个时候p里面存的是起始地址,str里面存的是NULL
  5. GetMemory结束运行,但没有返回任何值,这个时候p里面存的还是起始地址,str里面存的还是NULL
  6. 用strcpy函数将字符串赋值给str所指向的空间,但是str是空指针,上一篇文章里面说过对空指针解引用会使系统崩溃。
    这就是这段程序的主要问题。
    解决方法:
    方法1:将p存放的地址返回
char* GetMemory()
{
	char* p = (char*)malloc(100);
	return p;
}
void Test(void)
{
	char* str = NULL;
	str=GetMemory();
	strcpy(str, "hello world");
	printf(str);
}
int main()
{
	Test();
	return 0;
}

在这里插入图片描述
方法2:用二级指针存放str的地址,利用str的地址来改变str的值

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

在这里插入图片描述

题目2:

这个不是关于动态内存的,只是与上一个题有点类似。

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

先来看一下运行结果:
在这里插入图片描述
它打印了一堆烫烫烫,OK,他为什么这么烫呢?
原因:
这段代码是用数组创建的的空间,要知道数据跟变量一样,有着自己的作用域与生命周期,他在GetMemory函数中创建,那GetMemory运行结束就会释放这块空间。
当返回Test函数时,p的数组以及释放完成,这个时候我们把p存放的地址传给str,依旧可以找到这块空间,但是这块空间已经不属于这段代码,str就是野指针,对str进行操作就是访问野指针,形成非法访问,从而打印一串乱码。

题目3:

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

大家看一下这段代码,发现跟我在上面写的方法二几乎一模一样,那他有什么问题呢?
运行后发现,它可以正常打印,并且编译器没有出现任何警告和报错。
但是他忘了最重要一点,开辟的动态内存使用完后要及时释放,不然会在一些情况下造成一些严重的后果。
在写这个题目时我也发现我上面的那两段代码没有及时释放空间,希望你们能引以为戒,防止跟我一样出现这种低级的错误。

题目4:

void Test(void)
 {
 char *str = (char *) malloc(100);
 strcpy(str, "hello");
 free(str);
 //-------------------
 if(str != NULL)
 {
 strcpy(str, "world");
 printf(str);
 }
 }

这段代码在分隔符前面没什么问题,但是他在释放空间后没有给str赋值NULL,而又对str进行了判断以及操作。
要知道释放空间后str指向的内容已经释放,str这时已经是一个野指针了,对野指针进行相关操作就是非法访问,程序就会直接中断报错。
--------------------------------------------分隔符
这篇是对前面几篇内容的练习,可以让刚接触到动态内存分配的人对它做一个回顾与复习。
感谢各位的观看,有错请指正,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值