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

自定义C++ DLL调用new分配内存时崩溃的问题排查

问题描述

自行开发了一个C++ DLL,通过LoadLibrary/GetProcAddress调用其方法时,只要DLL中使用new操作符分配内存,调用该方法的test_app.exe就会崩溃。栈上分配内存(如std::array<int, 5> arr;)则无问题。

完整代码

test_app.cpp

#include <windows.h>

int main()
{
    typedef int (*Test)();
    HINSTANCE hGetProcTest = LoadLibraryA("DLLFunctions.dll");
    Test test_method = (Test)GetProcAddress(hGetProcTest, "Test");
        
    test_method();

    return 0;
}

dll_entry_point.cpp

#include <windows.h>

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  return 1;
}

int WINAPI WinMain(      
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{  
  return 0;
}

dll_functions.h

#ifndef UnitFunctionsH
#define UnitFunctionsH

#ifdef __cplusplus
extern "C"
{
#endif

__declspec (dllexport) int Test();

#ifdef __cplusplus
}
#endif

#endif

dll_functions.cpp

#include "dll_functions.h"
#include <array>

int Test()
{
    // Crash Happens Here
    std::array<int, 5> *arr = new std::array<int, 5>;
    return 1;
}

运行错误

Thread 1 received signal SIGSEGV, Segmentation fault.
0x00000000000094d8 in ?? ()

编译命令

g++ -g -c dll_entry_point.cpp &&
g++ -g dll_functions.cpp dll_entry_point.o -o DLLFunctions.dll &&
g++ -g test_app.cpp -o test_app

问题原因

GCC编译DLL时默认会静态链接C++标准库,导致DLL和主程序各自拥有独立的C运行时实例与堆空间。new操作依赖C运行时的堆管理逻辑,跨模块(主程序与DLL)使用独立堆会引发内存管理冲突,最终触发段错误。

解决办法

让DLL与主程序动态链接同一个C++标准库,确保两者共享运行时实例与堆空间,修改编译命令如下:

  1. 编译DLL:添加-shared(生成DLL必需)、-fPIC(位置无关代码,DLL必需)、-lstdc++(动态链接C++标准库)选项
g++ -g -c -fPIC dll_entry_point.cpp &&
g++ -g -shared -fPIC dll_functions.cpp dll_entry_point.o -o DLLFunctions.dll -lstdc++
  1. 编译主程序:同样指定动态链接C++标准库
g++ -g test_app.cpp -o test_app -lstdc++

额外注意事项

  • 确保DLL与主程序使用相同版本的GCC编译,避免运行时库版本不兼容
  • 后续若需释放DLL中分配的内存,需保证delete与new在同一个模块执行,或使用共享堆分配方式
  • dll_entry_point.cpp中的WinMain属于冗余代码,DLL无需WinMain入口,可安全删除(不影响崩溃问题修复)

内容的提问来源于stack exchange,提问作者Patrick Ryan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:05:24