VS运行库多线程MT和多线程MD的区别

VS运行库多线程MT和多线程MD的区别

文章目录

  • VS运行库多线程MT和多线程MD的区别
    • 1 链接的运行时库不一样
    • 2 全局堆句柄不一样
    • 3 编译出来的PE文件大小区别
    • 4 运行效率
    • 5 总结

多线程MT加载的是静态运行时库,属于C语言版本。

而多线程MD版本加载是动态运行时库,属于微软版本。

在工程属性窗体中选择配置属性,C++选项的代码生成多线程调试 DLL (/MDd)和多线程调试 DLL (/MTd)是Debug版本,后面没有d的是Release版本。

1 链接的运行时库不一样

多线程MT是 "multithread, static version ” 意思是多线程静态的版本,定义了它后,编译器把LIBCMT.lib 安置到OBJ文件中,让链接器使用LIBCMT.lib 处理外部符号;

多线程MD是 "multithread- and DLL-specific version” ,意思是多线程DLL版本,定义了它后,编译器把 MSVCRT.lib 安置到OBJ文件中,它连接到DLL的方式是静态链接,实际上工作的库是MSVCRxx.DLL

静态运行时库:LIBCMT.lib

动态运行时库:MSVCRT.lib + MSVCRxx.DLL

所以在使用多线程MT时候要配合静态库来使用,使用多线程MD的时候要配合动态库来使用

2 全局堆句柄不一样

当某项目以MT(静态链接库)的形式嵌入到多个项目,则可能造成运行时库的内存管理有多份;

当多项目以MD(动态链接库)方式运作时,其内部会采用同一个堆,内存管理将被简化;

如果是一个多线程MT编译方式的程序,你写一个dll,导出一个函数,参数设置为vector,然后在exe中调用,当导出函数结束时就会崩溃掉。其实原因很简单,就是因为初始化向量空间时malloc内存的过程在exe中,而vector析构时会free内存,申请和释放的内存空间不一致

其实不管是new/delete还是malloc/free最终调用的都是HeapAlloc/HeapFree,而这个函数的第一个参数为一个全局的堆句柄,由CreateHeap创建,创建该全局堆句柄的尚且在main等系列主函数之前。事实上这种夸模块堆操作异常总结起来就是申请内存时HeapAlloc传入的句柄和释放该内存时HeapFree传入的句柄不一致引起的

所以使用多线程MD的方式可以使得A模块中申请的内存到B模块中释放不会出问题,也就是解决跨模块内存管理的问题。

3 编译出来的PE文件大小区别

多线程MT编译出来的文件体积要比多线程MD编译出来的大,因为MT是把对应的运行时库直接放到编译出来的PE文件当中,而MD却是运行的时候从第三方dll中获取运行时库,自己本身却不包含

4 运行效率

多线程MT编译出来的文件运行时不需要加载第三方dll所以运行效率要比多线程MD稍微高一点点,当然作为用户是完全感觉不到的

5 总结

目前市面上大部分的软件都使用的是多线程MD的方式,编译出来的文件小,所有运行时库统一,同时也让内存管理简单化,省去了跨模块内存访问带来的各种bug。

你可能感兴趣的:(C++,c++,visualstudio)