不要混合使用运行时库的静态版本和动态版本!!!!
2008-10-09 23:16
519 查看
不要混合使用运行时库的静态版本和动态版本!!!! 最近在开发一个项目,有比较多的dll模块,以前测试时一直没有发现问题,运行的很正常。今天要发布一个新版本了,就用Bounders Check检查了一下。乖乖,很多错误阿!全部都是:
Allocation Conflict: Attempting to call global_operator_delete on 0x01566E68; pointer was allocated by malloc.
真是奇怪了,看了n多代码,找不出问题所在,并且这个错误是在pair<string,string> 发现的,好像根本就不是我的问题。
又经历了n多回的看。。。。。。。
最后终于发现问题了。原来我所有dll模块在生成时用的是多线程调试(/MDd), 但是我的exe也就是访问dll的模块是用单线程调试(/MLd)生成的,但是有意思的是我有一个测试程式也是用“单线程调试(/MLd)”生成的,运行时确很正常。
问题解决了,小结一下:
(1)所有的模块,包括dll/exe等,都需要统一的“C Run-Time(CRT) library ” !!!!
(2)BoundersChecker真的很管用,能帮你找出很多问题,甚至是很多你都没有意识/察觉到的问题。
(3) MSVCR71.DLL(C run-time library (without iostream or standard C++ library) ) 和 MSVCP71.dll(Standard C++ Library) 访在和exe文件的同一目录下时,BounderChecker也会报 “Allocation Conflict: Attempting to call global_operator_delete on 0x01566E68; pointer was allocated by malloc.”这个错误。
MSVCR71.DLL : C run-time library (without iostream or standard C++ library)
MSVCP71.dll : Standard C++ Library)
附:
msdn:
警告 不要混合使用运行时库的静态版本和动态版本。在一个进程中有多个运行时库副本会导致问题,因为副本中的静态数据不与其他副本共享。链接器禁止在 .exe 文件内部既使用静态版本又使用动态版本链接,但您仍可以使用运行时库的两个(或更多)副本。例如,当与用动态 (DLL) 版本的运行时库链接的 .exe 文件一起使用时,用静态(非 DLL)版本的运行时库链接的动态链接库可能导致问题。(还应该避免在一个进程中混合使用这些库的调试版本和非调试版本)。
在Windows下有六种类型CRTLib(C运行库):
Reusable Library Switch Library Macro(s) Defined
----------------------------------------------------------------
Single Threaded /ML LIBC (none)
Static MultiThread /MT LIBCMT _MT
Dynamic Link (DLL) /MD MSVCRT _MT and _DLL
Debug Single Threaded /MLd LIBCD _DEBUG
Debug Static MultiThread /MTd LIBCMTD _DEBUG and _MT
Debug Dynamic Link (DLL) /MDd MSVCRTD _DEBUG, _MT, and _DLL
MT和MD都适用于多线程,其区别是:
MT为静态链接CRT,这样编译出来exe是自包含的,所以会相对大一些,但运行时不用再load CRT库。
MD为动态链接CRT,编译出来exe会小一些,运行时需要load CRT,性能有一点点损失。
任何工程都应该使用同样的CRT Library。即要么都是/ML,要么都是/MTD, 如此类推。
如果一个程序中混合使用不同类型的CRT,有时可以通过link,这样会存在不同CRT的copy,并导致以下问题:
1)在一个lib中new出来内存,在另一个lib中delete,会crash。
2)不能在多个lib中共享file handle。
3)一个lib中设置locale(本地化有关),不能在另一个lib中起作用。
当工程比较大,包含的lib很多,特别当有外部lib(Third party library)存在时,link很容易发生下面这样的错误。
LIBCMTD.lib(chsize.obj) : error LNK2005: __chsize already defined in MSVCRTD.lib(MSVCRTD.dll)
这说明,你的工程使用了不同类型的CRT。这个时候首先一定要坚信这个原则:整个工程用同样的CRT Lib就可以解决问题。然后耐心一一检查每个lib。
如果恰恰某个外部lib用MT,另一个用MD,这个时候就比较痛苦。
如果有他们源码,就编译一个MT or MD类型的lib,以统一使用一个类型CRT。
如果没有,那可能只好选择其他的lib。
另有msdn lib关于:
This topic discusses the various .lib files that comprise the C run-time libraries as well as their associated compiler options and preprocessor directives.
The following libraries contain the C run-time library functions.
If you link your program from the command line without a compiler option that specifies a C run-time library, the linker will use LIBC.LIB.
To build a debug version of your application, the _DEBUG flag must be defined and the application must be linked with a debug version of one of these libraries. For more information about using the debug versions of the library files, see CRT Debugging Techniques.
This version of Visual C++ is not conformant with the C99 standard.
The new iostream functions, as well as many other new functions, exist in the Standard C++ Library:
When you build a release version of your project, one of the basic C run-time libraries (LIBC.LIB, LIBCMT.LIB, and MSVCRT.LIB) is linked by default, depending on the compiler option you choose (single-threaded, multithreaded, or DLL). If you include a Standard C++ Library header in your code, a Standard C++ Library will be linked in automatically by Visual C++ at compile time. For example:
Allocation Conflict: Attempting to call global_operator_delete on 0x01566E68; pointer was allocated by malloc.
真是奇怪了,看了n多代码,找不出问题所在,并且这个错误是在pair<string,string> 发现的,好像根本就不是我的问题。
又经历了n多回的看。。。。。。。
最后终于发现问题了。原来我所有dll模块在生成时用的是多线程调试(/MDd), 但是我的exe也就是访问dll的模块是用单线程调试(/MLd)生成的,但是有意思的是我有一个测试程式也是用“单线程调试(/MLd)”生成的,运行时确很正常。
问题解决了,小结一下:
(1)所有的模块,包括dll/exe等,都需要统一的“C Run-Time(CRT) library ” !!!!
(2)BoundersChecker真的很管用,能帮你找出很多问题,甚至是很多你都没有意识/察觉到的问题。
(3) MSVCR71.DLL(C run-time library (without iostream or standard C++ library) ) 和 MSVCP71.dll(Standard C++ Library) 访在和exe文件的同一目录下时,BounderChecker也会报 “Allocation Conflict: Attempting to call global_operator_delete on 0x01566E68; pointer was allocated by malloc.”这个错误。
MSVCR71.DLL : C run-time library (without iostream or standard C++ library)
MSVCP71.dll : Standard C++ Library)
附:
msdn:
警告 不要混合使用运行时库的静态版本和动态版本。在一个进程中有多个运行时库副本会导致问题,因为副本中的静态数据不与其他副本共享。链接器禁止在 .exe 文件内部既使用静态版本又使用动态版本链接,但您仍可以使用运行时库的两个(或更多)副本。例如,当与用动态 (DLL) 版本的运行时库链接的 .exe 文件一起使用时,用静态(非 DLL)版本的运行时库链接的动态链接库可能导致问题。(还应该避免在一个进程中混合使用这些库的调试版本和非调试版本)。
在Windows下有六种类型CRTLib(C运行库):
Reusable Library Switch Library Macro(s) Defined
----------------------------------------------------------------
Single Threaded /ML LIBC (none)
Static MultiThread /MT LIBCMT _MT
Dynamic Link (DLL) /MD MSVCRT _MT and _DLL
Debug Single Threaded /MLd LIBCD _DEBUG
Debug Static MultiThread /MTd LIBCMTD _DEBUG and _MT
Debug Dynamic Link (DLL) /MDd MSVCRTD _DEBUG, _MT, and _DLL
MT和MD都适用于多线程,其区别是:
MT为静态链接CRT,这样编译出来exe是自包含的,所以会相对大一些,但运行时不用再load CRT库。
MD为动态链接CRT,编译出来exe会小一些,运行时需要load CRT,性能有一点点损失。
任何工程都应该使用同样的CRT Library。即要么都是/ML,要么都是/MTD, 如此类推。
如果一个程序中混合使用不同类型的CRT,有时可以通过link,这样会存在不同CRT的copy,并导致以下问题:
1)在一个lib中new出来内存,在另一个lib中delete,会crash。
2)不能在多个lib中共享file handle。
3)一个lib中设置locale(本地化有关),不能在另一个lib中起作用。
当工程比较大,包含的lib很多,特别当有外部lib(Third party library)存在时,link很容易发生下面这样的错误。
LIBCMTD.lib(chsize.obj) : error LNK2005: __chsize already defined in MSVCRTD.lib(MSVCRTD.dll)
这说明,你的工程使用了不同类型的CRT。这个时候首先一定要坚信这个原则:整个工程用同样的CRT Lib就可以解决问题。然后耐心一一检查每个lib。
如果恰恰某个外部lib用MT,另一个用MD,这个时候就比较痛苦。
如果有他们源码,就编译一个MT or MD类型的lib,以统一使用一个类型CRT。
如果没有,那可能只好选择其他的lib。
另有msdn lib关于:
Run-Time Library Reference |
C Run-Time Libraries
See Also
Run-Time Library ReferenceThis topic discusses the various .lib files that comprise the C run-time libraries as well as their associated compiler options and preprocessor directives.
The following libraries contain the C run-time library functions.
C run-time library (without iostream or standard C++ library) | Characteristics | Option | Preprocessor directives |
---|---|---|---|
LIBC.LIB | Single-threaded, static link | /ML | |
LIBCMT.LIB | Multithreaded, static link | /MT | _MT |
MSVCRT.LIB | Multithreaded, dynamic link (import library for MSVCR71.DLL). Be aware that if you use the Standard C++ Library, your program will need MSVCP71.DLL to run. | /MD | _MT, _DLL |
LIBCD.LIB | Single-threaded, static link (debug) | /MLd | _DEBUG |
LIBCMTD.LIB | Multithreaded, static link (debug) | /MTd | _DEBUG, _MT |
MSVCRTD.LIB | Multithreaded, dynamic link (import library for MSVCR71D.DLL) (debug) | /MDd | _DEBUG, _MT, _DLL |
To build a debug version of your application, the _DEBUG flag must be defined and the application must be linked with a debug version of one of these libraries. For more information about using the debug versions of the library files, see CRT Debugging Techniques.
This version of Visual C++ is not conformant with the C99 standard.
Standard C++ Library
Note that starting in Visual Studio .NET 2003, Visual C++ will no longer ship the old iostream libraries. For details, see Upgrade to the Standard C++ Library and the Standard C++ Library Overview.The new iostream functions, as well as many other new functions, exist in the Standard C++ Library:
Standard C++ Library | Characteristics | Option | Preprocessor directives |
---|---|---|---|
LIBCP.LIB | Single-threaded, static link | /ML | |
LIBCPMT.LIB | Multithreaded, static link | /MT | _MT |
MSVCPRT.LIB | Multithreaded, dynamic link (import library for MSVCP71.dll) | /MD | _MT, _DLL |
LIBCPD.LIB | Single-threaded, static link | /MLd | _DEBUG |
LIBCPMTD.LIB | Multithreaded, static link | /MTd | _DEBUG, _MT |
MSVCPRTD.LIB | Multithreaded, dynamic link (import library for MSVCP71D.DLL) | /MDd | _DEBUG, _MT, _DLL |
相关文章推荐
- 不要混合使用运行时库的静态版本和动态版本
- 不要混合使用运行时库的静态版本和动态版本!!!!
- 不要混合使用运行时库的静态版本和动态版本
- 不要混合使用运行时库的静态版本和动态版本!!!!
- 不要混合使用运行时库的静态版本和动态版本
- 不要混合使用运行时库的静态版本和动态版本!!!!
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- 不要再build.gradle中使用动态版本的依赖
- 如何在存在动态版本的库时使用静态版本的库
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- 【Android开发学习44】android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- android 开发零起步学习笔记(十五):android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- 如何在存在动态版本的库时使用静态版本的库
- hive分区partition(动态和静态分区混合使用; partition的简介)
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- hive分区partition(动态和静态分区混合使用; partition的简介)