本节重点内容:
- 对NULL指针的解引用操作
- 对动态开辟空间的越界访问
- 对非动态开辟内存使用free释放
- 使用free释放一块动态开辟内存的一部分
- 对同一块动态内存多次释放
- 动态开辟内存忘记释放(内存泄漏)
- 经典的笔试题
⚡对NULL指针的解引用操作
⚡对动态开辟空间的越界访问
⚡ 对非动态开辟内存使用free释放
⚡使用free释放一块动态开辟内存的一部分
⚡对同一块动态内存多次释放
⚡动态开辟内存忘记释放(内存泄漏)
使用 malloc、calloc、realloc 函数申请的空间,如果不想使用,需要 free 释放,如果不使用 free 释放,在程序结束后,也会由操作系统进行回收。
如果没有使用 free 释放,程序也不结束,所申请的空间既没有使用,也没有释放,也没有回收,我们将这种情况称为内存泄漏。
解决方法是:自己申请的,自己释放。自己不方便释放的,告诉别人进行释放。
⚡经典的笔试题
题目1:请问运行Test 函数有哪些的错误?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.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);
return 0;
}
错误处:
- 调用 GetMemory 函数的时候,str 的传参为值传递,p 是 str 的临时拷贝,所以在GetMemory 函数内部将动态开辟空间的地址存放在 p 中的时候,不会影响 str 。所以 GetMemory 函数返回之后,str 中依然是 NULL 指针。strcpy 函数就会调用失败,原因是对 NULL 的解引用操作,程序会崩溃。
- GetMemory 函数内容 malloc 申请的空间没有机会释放,造成了内存泄漏。
解决方案一:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory( )
{
char* p = (char*)malloc(100);
return p;
}
int main()
{
char* str = NULL;
str = GetMemory( );
strcpy(str, "hello world");
printf(str);
free(str);
str = NULL;
return 0;
}
解决方案二:
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;
return 0;
}
代码运行结果如下:
题目2:请问运行Test 函数有哪些的错误?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory(void)
{
char p[] = "hello world";
return p;
}
int main()
{
char* str = NULL;
str = GetMemory();
printf(str);
}
错误处:返回栈空间地址的问题
- GetMemory 函数内部有创建的数组是临时的,虽然返回了数组的起始地址给了 str ,但是数组的内存出了 GetMemory 函数就被回收了,而 str 依然保存着数组的起始地址,这时如果使用 str ,str 就是野指针。
解决方案:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory()
{
static char p[] = "hello world";
return p;
}
int main()
{
char* str = NULL;
str = GetMemory();
printf(str);
}
代码运行结果如下:
题目3:请问运行Test 函数有哪些的错误?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
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;
}
错误处:内存泄漏
解决方案:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
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 函数有哪些的错误?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
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;
}
错误处:栈空间的非法访问
解决方案:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
str = NULL;
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
int main()
{
Test();
return 0;
}
感谢大家能够看完这篇博客,创作时长,小伙伴们觉得我的博客对你有帮助,不妨留下你的点赞的收藏,关注我,带你了解不一样的C语言。