内存泄漏 | 双向链表

‌一、内存泄漏

是指程序中已动态分配的堆内存由于某种原因未被释放或无法释放,导致系统内存的浪费,最终可能导致程序运行速度减慢甚至系统崩溃。‌ 内存泄漏是一个常见的问题,尤其在长时间运行的程序中更为突出,因为它会导致系统资源的逐渐耗尽。

①内存泄漏的原因
  1. ‌未释放动态分配的内存‌:在许多编程语言中,程序员需要手动分配和释放内存。如果忘记或错误地释放已经分配的内存,就会导致内存泄漏。

  2. ‌引用计数错误‌:在一些语言中,内存管理是通过引用计数实现的。如果引用计数错误,例如增加引用计数但未相应减少,也会导致内存泄漏。

  3. ‌循环引用‌:两个或多个对象相互引用,形成一个循环链表,如果这些对象没有被其他部分访问,但它们之间存在引用,那么它们的引用计数永远不会为零,导致内存泄漏。

  4. ‌文件未关闭‌:程序打开文件或网络连接后未正确关闭,也会导致系统资源泄漏,包括内存泄漏。

②内存泄漏的后果

• ‌程序性能下降‌:随着内存泄漏的积累,程序可用的内存逐渐减少,导致程序运行速度变慢。

• ‌系统崩溃‌:严重的内存泄漏会导致系统内存耗尽,引发程序崩溃或系统变慢等问题。

• ‌频繁的垃圾回收‌:为了清理不再使用的对象,垃圾回收器会频繁运行,导致程序暂停(Stop-The-World,STW)次数增加,用户体验变差。

③如何避免内存泄漏
  1. ‌及时释放资源‌:确保在使用完资源后关闭文件、数据库连接等,避免长时间占用内存。

  2. ‌设置合理的变量作用域‌:避免创建过大的对象或数据结构,及时清理不再需要的对象。

  3. ‌使用弱引用‌:在一些情况下,使用弱引用来管理对象可以避免强引用导致的对象无法被垃圾回收。

  4. ‌定期审查代码‌:定期检查代码中的内存管理逻辑,确保没有遗漏的内存释放操作。

  5. ‌使用内存检测工具‌:利用专业的内存检测工具来发现和定位内存泄漏问题。

通过以上方法,可以有效预防和解决内存泄漏问题,确保程序的稳定性和性能。

二、单双链表

单双链表图示

1.区别
  1. 单向链表只有一个指向下一结点的指针,双向链表除了有一个指向下一结点的指针外,还有一个指向前一结点的指针。
  2. 单链表只能单向读取,双向链表可以通过ppre快速找到前一结点。
2.双链表的优缺点

优点:可以找到前驱和后继,可进可退;

缺点:增加删除节点复杂,需要多分配一个指针存储空间

3.单向链表的逆序:先把链表断开,将头指针置为NULL
cs 复制代码
void reverse_link(Link_t *plink)
{
	if (is_empty_link(plink))
		return;

	Link_Node_t *pinsert = NULL;
	Link_Node_t *ptmp = plink->phead;
	plink->phead = NULL;
	
	while (ptmp != NULL)
	{
		pinsert = ptmp;
		ptmp = ptmp->pnext;

		pinsert->pnext = plink->phead;
		plink->phead = pinsert;
	}
}
4.单向链表的插入排序:
cs 复制代码
void insert_sort_link(Link_t *plink)
{
	if (is_empty_link(plink) || 1 == plink->clen)
	{
		return;
	}
	
	Link_Node_t *p = NULL;
	Link_Node_t *pinsert = NULL;
	Link_Node_t *ptmp = plink->phead->pnext;
	plink->phead->pnext = NULL;

	
	while (ptmp != NULL)
	{
		pinsert = ptmp;
		ptmp = ptmp->pnext;

		if (pinsert->data <= plink->phead->data)
		{
			pinsert->pnext = plink->phead;
			plink->phead = pinsert;
		}
		else
		{
			p = plink->phead;
			while (p->pnext != NULL && p->pnext->data < pinsert->data)
			{
				p = p->pnext;
			}
			pinsert->pnext = p->pnext;
			p->pnext = pinsert;
		}

	}
}
相关推荐
阿让啊1 小时前
C语言strtol 函数使用方法
c语言·数据结构·c++·单片机·嵌入式硬件
superlls4 小时前
(算法 哈希表)【LeetCode 349】两个数组的交集 思路笔记自留
java·数据结构·算法
Ripple123125 小时前
数据结构:顺序表与链表
数据结构·链表
一个响当当的名号6 小时前
B树,B+树,B*树(无代码)
数据结构·b树
古译汉书8 小时前
嵌入式铁头山羊stm32-ADC实现定时器触发的注入序列的单通道转换-Day26
开发语言·数据结构·stm32·单片机·嵌入式硬件·算法
野犬寒鸦8 小时前
力扣hot100:相交链表与反转链表详细思路讲解(160,206)
java·数据结构·后端·算法·leetcode
GalaxyPokemon8 小时前
LeetCode - 1089. 复写零
数据结构
失散138 小时前
分布式专题——1.2 Redis7核心数据结构
java·数据结构·redis·分布式·架构
zzzsde10 小时前
【数据结构】强化训练:从基础到入门到进阶(1)
数据结构
奔跑吧 android10 小时前
【linux kernel 常用数据结构和设计模式】【数据结构 3】【模拟input子系统input_dev和input_handler之间的多对多关系】
linux·数据结构·input·kernel·input_dev·input_handler·input_handle