为何在free_ps中调用free_p时,free(p)会触发无效指针错误?
问题分析与解决方案
错误原因
问题核心是内存分配与释放不匹配:
- 通过
partition_factory创建的partition是单独用malloc分配的独立内存块,此时调用free(p)完全合法。 - 但执行
add_p_to_ps时,代码做的是ps->partitions[ps->last] = *p;——这是结构体值拷贝,把p指向的结构体内容复制到了ps->partitions数组的某个元素位置上。 ps->partitions是一块整体通过malloc分配的数组内存,数组里的每个partition元素并不是单独malloc出来的独立内存块,只是数组的一部分。当你在free_p里对&ps->partitions[i]调用free(p)时,本质是试图释放数组内部的某个元素地址,违反了malloc/free的匹配规则(只能释放malloc/calloc/realloc返回的顶层指针),因此触发munmap_chunk(): invalid pointer错误。
另外原代码还有隐藏问题:调用add_p_to_ps完成值拷贝后,若不手动释放原partition_factory创建的p,会造成内存泄漏——因为ps中存储的是拷贝后的结构体,原p的内存会无人管理。
正确的释放方式
你修改后的代码是完全正确的,不会产生内存泄漏,逻辑如下:
- 遍历
ps->partitions数组,释放每个partition的elements指针(这是单独malloc的内存)。 - 释放整个
ps->partitions数组(整体malloc的内存块)。 - 释放
ps结构体本身(单独malloc的内存块)。
如果想保留free_p函数,需区分使用场景:仅当partition是partition_factory创建的独立内存块时,才调用free_p;对于ps->partitions数组内的元素,只需释放其elements即可。
优化后的完整释放代码(可选)
// 仅用于释放单独malloc的partition(比如partition_factory创建的实例) void free_p(partition* p){ if(p==NULL) return; if(p->elements) free(p->elements); free(p); } // 释放partitions结构体 void free_ps(partitions* ps){ if(ps==NULL) return; for(int i=0; i<=ps->last; i++){ // 数组内的元素不是独立malloc的,仅释放其elements free(ps->partitions[i].elements); } free(ps->partitions); free(ps); }
额外注意点
调用add_p_to_ps后,记得释放原partition指针,避免内存泄漏:
partition* p = partition_factory(4); // 往p中添加元素操作... add_p_to_ps(ps, p); free_p(p); // 释放原p的内存,ps中已存储拷贝后的内容
内容的提问来源于stack exchange,提问作者SKOP_
相关产品推荐
相关产品推荐

