如何在析构函数中释放malloc分配的成员变量内存?解决valgrind报错
问题分析与解决方案
你的代码存在多个致命问题,直接导致了valgrind的非法释放错误和内存泄漏:
- malloc的内存直接丢失:构造函数中刚用
malloc分配内存给page_frames,立刻就被循环里的new Page[PAGE_SIZE]覆盖了原始指针,malloc分配的内存地址彻底丢失,直接造成泄漏。 - 指针被非法偏移:循环里每次执行
page_frames++,最终page_frames指向的已经不是malloc返回的原始起始地址。free只能释放malloc返回的初始指针,释放偏移后的地址必然触发非法释放错误。 - 混用内存管理机制且未释放new的内存:你混用了
malloc和new,而且循环中new出来的数组完全没有用delete[]释放,又会产生大量内存泄漏。
正确的实现方式
方式1:统一使用malloc/free(适用于Page是POD类型,无自定义构造/析构函数)
// 构造函数 page_frames = (Page*)malloc(page_count * PAGE_SIZE); // 无需循环new,malloc已分配足够连续内存 // 析构函数 free(page_frames); page_frames = nullptr; // 避免野指针
方式2:统一使用new[]/delete[](适用于Page需要调用构造/析构函数)
如果Page有自定义构造逻辑,需要用new来创建对象:
// 构造函数:先创建指针数组,再逐个分配页帧 page_frames = new Page*[page_count]; for (uint32_t i = 0; i < page_count; ++i) { page_frames[i] = new Page[PAGE_SIZE]; } // 析构函数:先释放每个页帧数组,再释放指针数组 for (uint32_t i = 0; i < page_count; ++i) { delete[] page_frames[i]; } delete[] page_frames; page_frames = nullptr;
关键注意事项
- 绝对不能混用
malloc/free和new/delete两套内存管理机制,否则会触发未定义行为。 - 必须始终保存内存分配的原始起始地址,释放时只能使用该地址,不能用偏移后的指针。
内容的提问来源于stack exchange,提问作者iFrostBytes
相关产品推荐
相关产品推荐

