前言
如果说动态内存是C语言给我们的一个工具,那么只有掌握了工具的特点我们才能更好地使用。
紧随上卷,我们再来看看动态内存另外两道经典的笔试题。
(建议没看过上卷的朋友可以先看完上卷再回来:【C语言】动态内存经典笔试题(上卷)-CSDN博客)
另外,如果光看想不出来的话,别忘了你还可以画图。
第三题
以下代码的运行结果是什么?为什么?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
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;
}
分析:
这个代码与“动态内存经典笔试题(上卷)”的第一题十分相似,但是这里确实传的是&str,接收用的是char**,好像没有什么问题了。
其实,这个hello确实能打印,但是这块空间是我们动态开辟来的,而这个代码中并没有对其释放,所以存在的问题是内存泄漏。
改正:
那么这个改正只需要free和置空指针就行了:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
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;
}
第四题
以下代码的运行结果是什么?为什么?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "word");
printf(str);
}
}
int main()
{
Test();
return 0;
}
分析:
我们首先申请了100字节的空间,将首地址交给str,然后free(str);就是将这块空间还给了操作系统,但是我们并没有将str置为空指针,所以str变为野指针,还是能找到这块空间,只是变成了非法访问,而且空间里的内容可能被修改了。
所以str!=NULL为真,会进入if语句,strcpy真的把"world"放进这块空间了(非法访问)。
改正:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
str = NULL;//改正
if (str != NULL)
{
strcpy(str, "word");
printf(str);
}
}
int main()
{
Test();
return 0;
}
这样就不会非法访问了。总结就是free完要置为空,避免成为野指针,造成非法访问。
到此,本文介绍,祝阅读愉快^_^