实现 malloc() 和 free() — 分割大块
上一篇文章探讨了内存块重用顺序对内存消耗的影响,并优化了函数以减少浪费。然而,另一个更严重的问题依然存在:一个巨大的内存块可能会占据多个小块本可利用的空间。例如,分配一大块内存,释放后,再分配两个更小的块:
void *ptr1 = abmalloc(128); void *ptr2 = abmalloc(8); abfree(ptr1); void *ptr3 = abmalloc(8); void *ptr4 = abmalloc(8);
这时,128字节的空闲块无法被8字节的请求利用,导致后续8字节块分配需要再次扩展堆,造成内存利用率低下。
解决这个问题,一种高效但复杂的方法是使用“bins”:按大小分组的块列表。另一种更简单的方案是将大块分割成更小的块。本文采用后者。
代码重构
首先,对代码进行轻微重构。header_new()
函数同时负责分配内存和初始化块头,这不利于代码的可读性和维护性。我们将它拆分成两个函数:
header_plug()
:将已初始化的块插入到前一个和下一个块之间。header_init()
:初始化块的元数据(大小和可用性)。
它们分别如下:
void header_init(header *header, size_t size, bool available) { header->size = size; header->available = available; } void header_plug(header *header, header *previous, header *next) { header->previous = previous; if (previous != NULL) { previous->next = header; } header->next = next; if (next != NULL) { next->previous = header; } }
header_new()
函数修改如下:
header *header_new(header *previous, size_t size, bool available) { header *header = sbrk(sizeof(header) size); header_init(header, size, available); header_plug(header, previous, NULL); return header; }
(abmalloc()
函数中 last->previous->next = last;
这行可以删除,因为 header_plug()
现在负责处理此逻辑。)
分割内存块
接下来,实现 header_split()
函数。给定一个块头和所需最小大小,如果原始块足够大,则将其分割成两部分:
- 所需大小的块;
- 剩余部分及其新的块头;
首先,检查块是否足够大:
header *header_split(header *header, size_t size) { size_t original_size = header->size; if (original_size >= size sizeof(header)) {
如果足够大,则分割块。首先,减小当前块的大小:
header->size = original_size - size - sizeof(header);
计算新块的指针:
header *new_header = (header 1) header->size; // Corrected pointer calculation
初始化新块的头:
header_init(new_header, size, true);
将新块连接到链表:
header_plug(new_header, header, header->next);
如果原始块是最后一个块,更新 last
指针:
if (header == last) { last = new_header; }
返回新块:
return new_header; } else { return header; } }
更新 abmalloc()
最后,修改 abmalloc()
函数,在找到可用块后,调用 header_split()
尝试分割它:
if (header->available && (header->size >= size)) { header = header_split(header, size); header->available = false; return (void*)(header 1); // Cast to void* for correct return type }
如果块可以分割,则返回新块;否则,返回原始块。
关于块分割的说明
需要注意的是,新块是在原始块的末尾创建的。虽然也可以在开头创建,但在末尾创建新块可以使新的空闲块更靠近旧块,提高下次 abmalloc()
调用的效率。
分割大块内存是改进内存管理的一步,但它也可能导致小块内存碎片化,从而导致更大的请求需要扩展堆。下一篇文章将探讨如何解决这个问题。
以上是实现 malloc() 和 free() — 分割大块的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

选择大宗交易平台时应考虑以下因素:1. 流动性:优先选择日均交易量超50亿美元的平台。2. 合规性:查看平台是否持有美国FinCEN、欧盟MiCA等牌照。3. 安全性:冷钱包存储比例和保险机制是关键指标。4. 服务能力:是否提供专属客户经理和定制化交易工具。

提供各种复杂的交易工具和市场分析。覆盖 100 多个国家,日均衍生品交易量超 300 亿美元,支持 300 多个交易对与 200 倍杠杆,技术实力强大,拥有庞大的全球用户基础,提供专业的交易平台、安全存储解决方案以及丰富的交易对。

2025年安全的数字货币交易所排名前十依次为:1. Binance,2. OKX,3. gate.io,4. Coinbase,5. Kraken,6. Huobi,7. Bitfinex,8. KuCoin,9. Bybit,10. Bitstamp,这些平台均采用了多层次的安全措施,包括冷热钱包分离、多重签名技术以及24/7的监控系统,确保用户资金的安全。

常见的稳定币有:1. 泰达币(USDT),由Tether发行,与美元挂钩,应用广泛但透明性曾受质疑;2. 美元币(USDC),由Circle和Coinbase发行,透明度高,受机构青睐;3. 戴币(DAI),由MakerDAO发行,去中心化,DeFi领域受欢迎;4. 币安美元(BUSD),由币安和Paxos合作,交易和支付表现出色;5. 真实美元(TUSD),由TrustTo

截至2025年,稳定币交易所数量约为千家。1. 法定货币支持的稳定币包括USDT、USDC等。2. 加密货币支持的稳定币如DAI、sUSD。3. 算法稳定币如TerraUSD。4. 还有混合型稳定币。

选择可靠的交易所至关重要,Binance、OKX、Gate.io等十大交易所各具特色,CoinGecko、Crypto.com等新app也值得关注。

截至2025年4月,有七个加密货币项目被认为具有显着增长潜力:1. Filecoin(FIL)通过分布式存储网络实现快速发展;2. Aptos(APT)以高性能Layer 1公链吸引DApp开发者;3. Polygon(MATIC)提升以太坊网络性能;4. Chainlink(LINK)作为去中心化预言机网络满足智能合约需求;5. Avalanche(AVAX)以快速交易和
