4. 几个经典的笔试题
来自于书籍《高质量C/C++编程》
4.1 题目1:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.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:GetMemory函数内部创建指针p申请了100字节的空间,动态申请了内存,但是没有释放,会存在内存泄露。
问题2:Test函数调用,传递了一个指针str,str传给p的时候,p是str的临时拷贝,有自己独立的内存空间,当GetMemory函数内部申请空间之后,地址存放在p中,str依然是NULL
问题3:当GetMemory函数返回之后,调用strcpy()函数,相当于访问NULL指针,形成了非法访问内存。
如何修改为正确的代码
修改1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory()//修改1
{
char *p = (char*)malloc(100);
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory();
strcpy(str, "hello world");
printf(str);
free(str);
str = NULL;
}
int main()
{
Test();
return 0;
}
修改2
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void GetMemory(char** p)//修改2
{
* p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
free(str);
str = NULL;
}
int main()
{
Test();
return 0;
}
上面的两个代码都没有解决内存泄露的问题,只是解决了非法访问内存的问题,
我们在malloc内存之后就应该养成free的习惯。
4.2 题目2:
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
分析:这个地方的问题,我们一般称为返回栈空间地址的问题
它是由于。p在函数GetMemory()调用完成之后,就销毁了。
虽然我们拿到了p存放的地址就是“hello world”的首字符地址,
但是函数调用结束之后,为p[ ]开辟的空间就已经交还给操作系统了
我们在main函数中还要对其进行访问,是属于非法访问了,访问的内容,就是随机值,可能是我们的“hello world”,也可能是其他任意值。