在学习了动态内存开辟之后,下面给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;
}
解答:程序会崩溃。
- 传参时进行的是值传递,并且函数GetMemory并没有返回值,所以函数中p的地址并没有被带回到str中,str始终是NULL,所以当用字符串拷贝对str进行操作时,程序就会崩溃,因为NULL指针指向的空间是不能直接访问的。
- 函数GetMemory中开辟的动态内存没有释放,会造成内存泄漏。
改进:
- 让GetMemory函数把开辟的空间的地址带回来(可以采用传址调用,也可以让函数以返回值的形式把地址带回去)
- 动态开辟的空间在使用完后用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语言~