题目一:
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;
}
请问上述代码输出结果是什么,理由是什么?
答:不会输出
解析:
主要原因是str传参时传值传参,不会改变str本身的值,所以str经过函数操作后,仍然是空指针NULL,这样造成上述代码的两个问题:
- 对str空指针进行解引用操作(再strcmp内部需要解引用)
- 在GetMemory函数里对p开辟的动态空间没有释放,导致出GetMemory函数p这个临时变量销毁,导致内存泄露
TIP:printf函数另类打印字符串的方法
在题目中我们可以看到
char* p="hello world";
printf(str);
printf("hello world");
这两种方式打印字符串是等价的,因为第二种方式本质上也只是将字符串的首元素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就是一个野指针,在进行访问容易造成非法访问。
总结:
以后再遇到在自定义函数中返回局部变量,一定要注意非法访问的问题。
题目三:
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之后,立刻将原指针置为空指针。