You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在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的内存会无人管理。

正确的释放方式

你修改后的代码是完全正确的,不会产生内存泄漏,逻辑如下:

  1. 遍历ps->partitions数组,释放每个partition的elements指针(这是单独malloc的内存)。
  2. 释放整个ps->partitions数组(整体malloc的内存块)。
  3. 释放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_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 17:16:21