题目1
问: 有如下代码,Test()函数的运行结果如何?
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;
}
结果: 这条代码会运行出结果,但是并不会和我们预想的一样打印出“hello world”,而是一片空白。
存在问题:
- 在Test()函数中,虽然str是一个指针变量,但是调用GetMemory进行传参时,传过去的只是str这个指针变量的值,也就是说这是一次值传递。因此在GetMemory函数内部,给它的形参p开辟了一块空间,但是对函数外部的str指针并没有任何影响,当程序回到Test函数中时,str仍是一个空指针NULL,因此strcpy会失败,自然也就不会打印出任何东西了。
- GetMemory函数中给p在堆区上开辟出的动态内存空间在该函数销毁后也没有释放,这导致了内存泄漏!
修改之后: 这段代码的修改有多种方法,可以参考以下两种:
- GetMemory函数修改为有返回值,在Test函数最后释放动态内存空间:
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;
}
- GetMemory函数传参时使用地址传参,即Test函数内将&str传过去,GetMemory函数形参使用二级指针接收str地址。在Test函数最后释放动态内存空间:
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;
}
题目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;
}
结果: 运行后,打印出来的是一些乱码,而非预期的hello world。
存在问题: 这段代码和上面的代码的修改1很相似,但是为什么这里出现问题了呢?
这段代码本质上是局部变量的生命周期问题。GetMemory函数中创建的p数组,是创建在栈区 上的一个只存活于该函数内部的局部变量,当程序结束GetMemory函数后,在该函数内部创建的空间也都随之销毁。虽然传回了一个地址,但是该地址指向的空间的内容已经被销毁了,可能已经被其他内容占据,因此此处无法正确打印出hello world。
修改之后: 这里可以直接和题目1中一样,使用堆区动态空间。 也可以在调用GetMemory函数时进行传参。如下:
char* GetMemory(char pa[])
{
pa = "hello world";
return pa;
}
void Test(void)
{
char* str = NULL;
char p[] = { 0 };
str = GetMemory(p);
printf(str);
}
题目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);
}
存在问题: 此题其实和题目1一样,一眼可以看出没有free释放动态内存。其修改可参见题目1。
题目4
问: 请问运行Test 函数会有什么样的结果?
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
存在问题: 这段代码映入眼帘的可能是free的位置,有的同学或许会觉得是free释放太早。但重点并非如此,而是在free释放完动态空间后没有及时对动态空间的指针进行置空处理。
切记:用完动态内存开辟的空间之后一定要进行free释放,释放后再手动进行置空处理。
修改之后:
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
str = NULL;
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
题目5
问: 以下代码存在什么问题:
int* myFun()
{
int* str;
int a = 10;
str = &a;
return str;
}
分析: 这段代码主要存在野指针的问题。 str定义时没有初始化,我们不知道它指向哪里,贸然使用有安全问题。
|