题目1:
请问运行Test 函数会有什么样的结果?
#include<stdio.h>
#include<stdlib.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;
}
题目解析:这段代码会发生崩溃。
我们将str传给函数GetMemory,对str进行动态内存开辟,此时str指向了空间p,注意此时p只是形参,因此当程序出函数GetMemory后,str的值不会发生任何改变,同时,动态开辟的内存p不会被回收,这就造成了内存泄漏。
紧接着程序将进入strcpy函数,此时str为NULL,这时候strcpy函数仍然会对str进行解引用操作,对空指针进行解引用操作就会导致程序发生崩溃。
解决方案:将str的地址传过去,这是就用char**p接收了,此种方法就可以有效的对str开辟空间了。
#include<stdio.h>
#include<stdlib.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;
}
运行结果:
题目2:
请问运行Test 函数会有什么样的结果?
char* GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory();
printf(str);
}
int main()
{
test();
return 0;
}
题目解析:这段代码仍然得不到想要的结果。
我们将str传给了GetMemory函数,函数GetMemory在开辟了空间p,不过p存在于栈区,需要注意的是,栈区中的数据只在函数调用期间有效,一旦函数返回,栈帧被弹出,栈区中的数据就会被销毁。即使p的地址被传出了,str可以找到p空间的地址,但是p中的数据已经被销毁了。
解决方案:
1.可以使用static对p进行修饰,使p成为静态变量,静态变量具有全局生命周期,它们在程序执行期间一直存在,不会随着函数的调用和返回而被创建和销毁。
2.当然用malloc开辟空间,这样也是可行的。
题目3:
请问运行Test 函数会有什么样的结果?
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;
}
题目解析:这段代码也是存在问题的,问题出在没有对malloc开辟的空间进行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;
}
这样才是正确的写法。
题目4:
请问运行Test 函数会有什么样的结果?
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依然指向了malloc所开辟打空间,这就造成了野指针的问题。紧接着strcpy会访问str所指向的空间,但是str所指向的空间已经被释放掉了,这就会造成内存的非法访问。