跨模块内存管理 ‘__acrt_first_block == header’异常的解决方法
问题描述
在调用动态库dll的时候,程序有时会在dll中崩溃,并提示如下错误
解决方法
引起这个问题的原因是exe项目和dll项目的运行库设置的不统一造成了跨模块内存访问的问题,将exe项目和dll项目的运行库都设置成多线程MD就可以解决这个问题。
原因分析
exe运行库的链接方式为MD,而dll的链接方式为MT。
“/MT和/MTd表示采用多线程CRT库的静态lib版本。该选项会在编译时将运行时库以静态lib的形式完全嵌入。该选项生成的可执行文件运行时不需要运行时库dll的参加,会获得轻微的性能提升,但最终生成的二进制代码因链入庞大的运行时库实现而变得非常臃肿。当某项目以静态链接库的形式嵌入到多个项目,则可能造成运行时库的内存管理有多份,最终将导致致命的“Invalid Address specified to RtlValidateHeap”问题。另外托管C++和CLI中不再支持/MT和/MTd选项。
/MD和/MDd表示采用多线程CRT库的动态dll版本,会使应用程序使用运行时库特定版本的多线程DLL。链接时将按照传统VC链接dll的方式将运行时库MSVCRxx.DLL的导入库MSVCRT.lib链接,在运行时要求安装了相应版本的VC运行时库可再发行组件包(当然把这些运行时库dll放在应用程序目录下也是可以的)。 因/MD和/MDd方式不会将运行时库链接到可执行文件内部,可有效减少可执行文件尺寸。当多项目以MD方式运作时,其内部会采用同一个堆,内存管理将被简化,跨模块内存管理问题也能得到缓解。
/MD和/MDd将是潮流所趋,/MT和/MTd在非必要时最好也不要采用了。
参考文章:跨模块内存管理 ‘__acrt_first_block == header’异常_u010634308的专栏-程序员宅基地 - 程序员宅基地 (cxyzjd.com)