Hello,各位小伙伴们上期我们了解到了动态内存常见的错误,这期让我们来看看几道经典面试题
看看这段程序将会输出什么:
#include<stdio.h>
#include<stdlib.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)程序崩溃 (2)内存泄露
让我们一起来分析一下:
GetMemory(str)函数在进行传递参数的时候,是值传递(虽然创建的变量是指针变量但也是变量,并没有传递地址!)在定义部分参数接收后,开辟了动态内存空间,但出GetMemory(str)函数后指针变量p将会销毁,还给操作系统,str仍然是空指针,将hello world复制到str中去,会导致程序崩溃,同时在自定义函数中开辟的动态内存空间无法被释放,就会导致内存泄露的问题!
如果要进行修改可以从两方面进行改正:(1)将函数的值传递改为址传递,在自定义函数中使用二级指针来进行接收同时要在main函数中进行释放内存 (2) 使用一个指针变量来接收函数的返回值,同时把自定义函数的类型改为char*类型
继续试试这道题:
#include<stdio.h>
#include<stdlib.h>
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在出函数的时候被销毁了,虽然p的地址传递了回来,但指针变量p被销毁成为野指针,str在接收到野指针后会打印乱码!
运行截图:
继续加油:
#include<stdio.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;
}
运行结果是:hello
但会造成内存的泄露!在最后进行一下内存的释放即可
最后一道小题:
#include<stdio.h>
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;
}
出现的问题在于对str进行释放后会,如果没有及时把str置为NULL则会导致str为野指针,在判断语句中就会对野指针的一个访问!及时将str置为NULL就可以了!