题目一:请问:主函数的运行结果是什么??
void GetMemory(char* p)
{
p=(char*)malloc(100);
}
int main()
{
char* str=NULL;
GetMemory(str);
strcpy(str,"hello world");
printf(str);
}
答案:运行该代码程序会出现崩溃的现象,并且存在内存泄漏的问题
分析:
1.GetMemory函数中参数p只是str的一份临时拷贝,因为是值传递(也就是只传的是str这个指针,并没有传str这个指针的地址),所以在调用完GetMemory函数之后str还是原来的空指针
2.GetMemory函数中为指针p开辟了一块内存,但是并没有释放它,所以会造成内存泄漏
3.strcpy(str,"hello world")这条语句是导致程序崩溃的原因,因为指针str其实在调用完GetMemory函数之后还是空指针,所以给空指针赋值就会引起程序崩溃
代码改正:
法一:
#include<stdio.h>
#include<string.h>
void GetMemory(char** p)
{
*p=(char*)malloc(100);
}
int main()
{
char* str=NULL;
GetMemory(&str);
strcpy(str,"hello world");
printf(str);
free(str);
str=NULL;
}
法二:
#include<stdio.h>
#include<string.h>
char* GetMemory(char* p)
{
p=(char*)malloc(100);
return p;
}
int main()
{
char* str=NULL;
str=GetMemory(str);
strcpy(str,"hello world");
printf(str);
free(str);
str=NULL;
}
题目二:请 问 运 行 T e s t 函 数 会 有 什 么 样 的 结 果 ?(返回栈空间地址问题)
char* GetMemory(void)
{
char p[]="hello world";
return p;
}
void Test(void)
{
char* str=NULL;
str=GetMemory();
printf(str);
}
int main()
{
Test();
return 0;
}
答案:该运行程序会崩溃,具有非法访问内存的现象
分析:
跟题目一类似,当Test函数调用GetMemory函数之后,数组p会还给操作系统,所以虽然str指向的初始位置和p的起始位置相同,但是后面的内容已经不是“helllo world”,所以是一些随机值,再将这些随机值打印就会出现非法访问内存的现象
拓展:返回栈空间地址问题:拿上面这个题作为例子
开辟的数组p位于栈区,当调用完函数之后,在栈区开辟的内存会还给操作系统,所以如果函数的返回值返回栈空间地址会出现问题
举个例子:
#include<stdio.h>
int* test()
{
int a=10;
return &a;
}
int main()
{
int* p=test();
*p=20;
return 0;
}
并不只是返回数组名才称得上是返回栈空间地址问题,而是所有在栈区开辟的内存,以其地址作为返回值时都是这类问题