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

malloc后free函数异常:C++代码在free(arg)行崩溃,求助内存释放问题

解决C++中free(arg)崩溃但free(args)正常的问题

看起来你遇到了一个典型的内存管理+线程同步问题——free(arg)崩溃但free(args)能正常运行,大概率是下面几个原因导致的,我来帮你拆解并给出修复方案:

可能的崩溃原因

  • 内存重复释放:你的线程函数myFunc里的args其实是全局指针arg的拷贝(因为你把arg作为参数传给了线程),如果线程里已经调用free(args)释放了这块内存,主线程再调用free(arg)就属于二次释放内存,这是C/C++里的未定义行为,必然会导致崩溃。
  • 分配与释放函数不匹配:如果arg是用new关键字分配的(C++风格),却用C风格的free来释放,会触发未定义行为;而args对应的内存如果是用malloc分配的,free(args)就没问题,这会导致两者表现不一致。
  • 线程未结束就释放内存:如果主线程在myFunc还在运行、还在访问args指向的内存时,就调用free(arg),会导致访问已释放内存或者释放时线程正在操作内存,引发崩溃。

针对性解决方案

方案1:用智能指针彻底避免手动内存管理(推荐)

C++11及以后的标准提供了智能指针(比如std::unique_ptr),可以自动帮你管理内存生命周期,不用手动调用free/delete,从根源上避免释放错误。

修正后的代码示例:

#include "stdafx.h"
#include <process.h>
#include <iostream>
#include <windows.h>
#include <memory> // 引入智能指针头文件
using namespace std;

typedef struct {
    int StartNode;
    int EndNode;
} t;

// 用unique_ptr代替全局裸指针,自动管理内存
unique_ptr<t> arg;

unsigned int __stdcall myFunc(void *param) {
    t *args = static_cast<t*>(param);
    // 这里执行你的业务逻辑,比如访问节点数据
    cout << "处理节点:" << args->StartNode << " → " << args->EndNode << endl;

    // 注意:智能指针会自动释放内存,这里不要再调用free(args)!
    return 0;
}

int main() {
    // 用make_unique分配内存(C++14及以后支持,更早版本可以用unique_ptr<t>(new t))
    arg = make_unique<t>();
    arg->StartNode = 1;
    arg->EndNode = 10;

    // 创建线程,传入智能指针的裸指针(get()方法)
    HANDLE hThread = (HANDLE)_beginthreadex(nullptr, 0, myFunc, arg.get(), 0, nullptr);
    if (!hThread) {
        cerr << "线程创建失败!" << endl;
        return 1;
    }

    // 必须等待线程执行完毕,确保线程不再访问arg指向的内存
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);

    // 这里不需要手动free(arg),unique_ptr会在main函数结束时自动释放内存
    return 0;
}

方案2:如果坚持用裸指针,注意这几点

如果你必须使用裸指针手动管理内存,要严格遵守以下规则:

  1. 分配与释放匹配:
    • 如果用C风格分配:arg = (t*)malloc(sizeof(t));,必须用free(arg);释放;
    • 如果用C++风格分配:arg = new t;,必须用delete arg;释放(数组用delete[])。
  2. 只释放一次:要么线程执行完毕后由主线程释放,要么由线程自己释放,但不能两者都做。
  3. 线程同步等待:主线程必须调用WaitForSingleObject等待线程结束,确保线程已经不再访问这块内存后,再执行释放操作。

举个裸指针的正确示例:

#include "stdafx.h"
#include <process.h>
#include <iostream>
#include <windows.h>
using namespace std;

typedef struct {
    int StartNode;
    int EndNode;
} t;

t *arg;

unsigned int __stdcall myFunc(void *param) {
    t *args = static_cast<t*>(param);
    // 执行业务逻辑
    cout << "处理节点:" << args->StartNode << " → " << args->EndNode << endl;

    // 这里不要调用free(args),交给主线程释放
    return 0;
}

int main() {
    // C风格分配内存
    arg = (t*)malloc(sizeof(t));
    if (!arg) {
        cerr << "内存分配失败!" << endl;
        return 1;
    }
    arg->StartNode = 1;
    arg->EndNode = 10;

    HANDLE hThread = (HANDLE)_beginthreadex(nullptr, 0, myFunc, arg, 0, nullptr);
    if (!hThread) {
        cerr << "线程创建失败!" << endl;
        free(arg); // 分配成功但线程创建失败,要提前释放内存
        return 1;
    }

    // 等待线程结束
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);

    // 此时线程已不再访问内存,安全释放
    free(arg);
    arg = nullptr; // 避免野指针
    return 0;
}

内容的提问来源于stack exchange,提问作者Jop Hoeijmakers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:41:39