IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言】动态内存管理的常见错误以及解决方法 -> 正文阅读

[C++知识库]【C语言】动态内存管理的常见错误以及解决方法

1.对NULL指针的解引用操作

问题:当我们用malloc开辟动态内存失败时,指针将会是空指针。
一般申请的内存过大将会导致开辟动态内存失败。
看下面这个例子

void test()
{
	int* p = (int*)malloc(INT_MAX);//申请最大字节,申请的内存过大。
	*p = 20;
	free(p);
}

调用这个函数,并监视p
在这里插入图片描述
可以看到,p的值是0,也就是空指针。
解决
所以,我们在申请动态内存空间后,要判断它是否不为空指针,才进行一系列的操作。避免程序出现问题。

void test()
{
	int* p = (int*)malloc(INT_MAX);
	if (NULL == p)
	{
		perror("malloc");
		return; //如果为空指针,直接return结束
	}
	else
	{
		*p = 20;
	}
	free(p);
	p = NULL;
}

2.对动态开辟空间的越界访问

问题:
同数组一样,动态开辟的内存空间也可能被越界访问。

void test2()
{
	int* p = (int*)malloc(5 *sizeof(int));
	 //开辟了20个字节,只能存5个int类型的数据
	if (NULL == p)
	{
		perror("malloc");
		return;
	}
	else
	{
		for (int i = 0; i < 10; i++)//这里却要存10个int类型的数据
		{
			*(p + i) = i;
		}
	}
	free(p);
	p = NULL;
}

调用这个函数
在这里插入图片描述
程序直接崩溃。
解决:

void test2()
{
	int* p = (int*)malloc(5 * sizeof(int));
	if (NULL == p)
	{
		perror("malloc");
		return;
	}
	else
	{
		for (int i = 0; i < 5; i++)
		{
			*(p + i) = i;
		}
	}
	free(p);
	p = NULL;
}

1.尽量不要越界访问
2.可以在存满的情况下加个realloc

3.对非动态内存开辟使用free释放

问题:很多人刚学malloc的时候,知道malloc后一定要free释放,避免内存泄漏。
但是却常常走火入魔,写完一段程序就free,即使代码里面没有开辟动态内存。
比如:

int main()
{
	int a = 10;
	int* p = &a;
	free(p);
	p = NULL;
	return 0;
}

在这里插入图片描述

运行程序,直接崩溃
解决: free()是释放动态开辟的内存空间,不是什么都能释放的。

4.使用free释放动态开辟内存的一部分

free()释放动态开辟的内存空间的时候,括号里面放的是一定开辟空间的起始地址。
问题:
看下面这一段代码有什么问题?

int main()
{
	int* p = (int*)malloc(20);
	if (NULL == p)
	{
		return 1;
	}
	for (int i = 0; i < 5; i++)
	{
		*p = i;
		p++;  //p指向的地址改变了
	}
	free(p);
	p = NULL;
	return 0;
}

运行程序,程序也会崩溃。因为free(p),p不再指向空间的起始地址。
解决:

int main()
{
	int* p = (int*)malloc(20);
	if (NULL == p)
	{
		return 1;
	}
	for (int i = 0; i < 5; i++)
	{
		*(p + i) = i; //尽量不改变空间的起始地址
	}
	free(p);
	p = NULL;
	return 0;
}
int main()
{
	int* p = (int*)malloc(20);
	if (NULL == p)
	{
		return 1;
	}
	int* p2 = p; //如果非要改变p的地址,可以把p的起始地址给p2
	//free(p2)
	for (int i = 0; i < 5; i++)
	{
		*p = i;
		p++;
	}
	free(p2);
	p = NULL;
	p2 = NULL;
	return 0;
}

5.对同一块动态内存多次释放

问题:有时候我们写程序的时候,可能会因为粗心多次free了一个动态开辟的内存。 这就体现了free后,把指针置为空的重要性

int main()
{
	int* p = (int*)malloc(20);
	if (NULL == p)
	{
		return 1;
	}
	for (int i = 0; i < 5; i++)
	{
		*(p + i) = i;
	}
	free(p);
	
	//...   进行了一系列的代码后

	free(p);//上面free过了
}

运行程序,程序崩溃。
解决:

int main()
{
	int* p = (int*)malloc(20);
	if (NULL == p)
	{
		return 1;
	}
	for (int i = 0; i < 5; i++)
	{
		*(p + i) = i;
	}
	free(p);
	p = NULL; 把p置为空指针
	
	//...

	free(p);//free(NULL),free一个空指针,这段代码啥事也没干。
}

6.动态开辟内存忘记释放(内存泄漏)

比上面那些问题更严重的问题就是忘记释放,就会造成内存泄漏问题

void test()
{
	int* p = (int*)malloc(100);
	if (NULL != p)
	{
		*p = 20;
	}
}
int main()
{
	test();
	while (1);
}

大家可以运行这段程序,然后打开任务管理器看一下自己的程序CPU占比,不过不会一直升高,因为有自动保护机制。
解决:
正确的free动态开辟的内存空间。

总结:

对于动态开辟内存malloc,我们既然要向内存使用他的方便之处,就要懂得在使用完后怎么规范地还给内存。
有借有还,再借不难!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-25 23:05:06  更:2022-09-25 23:05:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 12:20:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码