动态内存管理(上)-CSDN博客(malloc, realloc, calloc, free函数的用法以及注意事项等知识点)
动态内存管理(中)-CSDN博客(常见的内存出错问题)
---------------------------------------------------------------------------------------------------------------------------------前两节复习了动态内存函数和常见内存出错的问题。 这节主要分析几个容易出错的问题加深印象。
目录
题目一:空指针解引用问题
题目二: 野指针的访问
题目三:二级指针修改指针实参
题目四:free后忘记将指针置空
题目一:空指针解引用问题
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;
}请看这么一道题, Test()哪里出错了呢?
其实这里在str函数传参时是穿的NULL值过去给p, 修改p并没有修改str, str仍为NULL, 后续对str赋值是对控制真的解引用。如下:
题目二: 野指针的访问
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函数虽然返回了一个指针, 但是这个指针是在它自己的栈帧空间申请的一处空间, 而GetMemory在调用完毕之后销毁函数栈帧, 操作系统回收内存, 返回的指针所指向的就是一块没有权限访问的内存了, 也就是野指针。
如图:
题目三:二级指针修改指针实参
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;
}
请问Test函数会有什么结果呢?
这道题是题目一的改正, 这个时候已经能够很好的打印hello了。
题目一我们知道是因为str传值, 修改形参不会修改实参。 而这个题将str的地址传送了过去, 想当于对于str的传址调用。 并且str是一个指针变量。 所以接收使用的二级指针。
关系如图:
题目四:free后忘记将指针置空
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;
}
请问Test中结果是什么?
会报错, 这又是野指针解引用问题。
str虽然free了, 但是str这个时候指向的还是刚刚堆区申请的那处空间的首地址。 这块地址不是空指针, 进入if语句后strcpy发生野指针访问问题。
如图: