CRT:C Run-Time Library, C 语言运行时库。
由来:
- 1) 运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数.
- 2) C 语言是所谓的“小内核”语言,就其语言本身来说很小(不多的关键字,程序流程控制,数据类型等);所以,C 语言内核开发出来之后,Dennis Ritchie 和 Brian Kernighan 就用 C 本身重写了 90% 以上的 UNIX 系统函数,并且把其中最常用的部分独立出来,形成头文件和对应的 LIBRARY,C run-time library 就是这样形成的。
- 3) 随后,随着 C 语言的流行,各个 C 编译器的生产商/个体/团体都遵循老的传统,在不同平台上都有相对应的 Standard Library,但大部分实现都是与各个平台有关的。由于各个 C 编译器对 C 的支持和理解有很多分歧和微妙的差别,所以就有了 ANSI C;ANSI C (主观意图上)详细的规定了 C 语言各个要素的具体含义和编译器实现要求,引进了新的函数声明方式,同时订立了 Standard Library 的标准形式。所以C运行时库由编译器生产商提供。至于由其他厂商/个人/团体提供的头文件和库函数,应当称为第三方 C 运行库(Third party C run-time libraries)。
- 4) C run-time library里面含有初始化代码,还有错误处理代码(例如divide by zero处理)。你写的程序可以没有math库,程序照样运行,只是不能处理复杂的数学运算,不过如果没有了C run-time库,main()就不会被调用,exit()也不能被响应。因为C run-time library包含了C程序运行的最基本和最常用的函数。
- 5) 到了 C++ 世界里,有另外一个概念:Standard C++ Library,它包括了上面所说的 C run-time library 和 STL。包含 C run-time library 的原因很明显,C++ 是 C 的超集,没有理由再重新来一个 C++ run-time library. VC针对C++ 加入的Standard C++ Library主要包括:LIBCP.LIB, LIBCPMT.LIB和 MSVCPRT.LIB
- 6) Windows环境下,VC提供的 C run-time library又分为动态运行时库和静态运行时库。 动态运行时库主要是DLL库文件msvcrt.dll(or MSVCRTD.DLL for debug build),对应的Import library文件是MSVCRT.LIB(MSVCRTD.LIB for debug build) 静态运行时库(release版)对应的主要文件是: LIBC.LIB (Single thread static library, retail version) LIBCMT.LIB (Multithread static library, retail version) msvcrt.dll提供几千个C函数,即使是像printf这么低级的函数都在msvcrt.dll里。其实你的程序运行时,很大一部分时间时在这些运行库里运行。在你的程序(release版)被编译时,VC会根据你的编译选项(单线程、多线程或DLL)自动将相应的运行时库文件(libc.lib,libcmt.lib或Import library msvcrt.lib)链接进来。 编译时到底哪个C run-time library联入你的程序取决于编译选项: /MD, /ML, /MT, /LD (Use Run-Time Library) 你可以VC中通过以下方法设置选择哪个C run-time library联入你的程序
- 从程序可移植性考虑,如果两函数都可完成一种功能,选运行时库函数好,因为各个 C 编译器的生产商对标准C Run-time library提供了统一的支持.
typedef int (__cdecl * _CRT_ALLOC_HOOK)(int, void *, size_t, int, long, const unsigned char *, int);
_CRT_ALLOC_HOOK _CrtSetAllocHook( _CRT_ALLOC_HOOK allocHook );
参数:allocHook 监听 C Run-time debug 时候内存申请释放的钩子函数 .
返回值:
返回先前设置的钩子函数,如果没有设置过,就返回NULL
设置钩子后,在C Run-time中进行内存的 allocate, reallocate 以及 free 操作前都会触发钩子函数
上述钩子函数只有在定义了_DEBUG的时候才生效.
自定义的钩子函数如下:
int user_allocHook(int allocType, void* userData, size_t size, int blockType, long requestNumber, const unsigned char* filename, int lineNumber);
// 返回TRUE 示意继续分配,返回FALSE 示意分配器拒绝当前操作,操作失败
参数:
allocType 内存操作类型, (_HOOK_ALLOC, _HOOK_REALLOC, and _HOOK_FREE)
userData 内存操作数据,当操作类型为 _HOOK_ALLOC 时, userData为空
size 当前操作的内存block的大小
blockType 当前操作的内存block的类型 (_FREE_BLOCK, _NORMAL_BLOCK, _CRT_BLOCK, _IGNORE_BLOCK, _CLIENT_BLOCK, _MAX_BLOCKS)
requestNumber 当前操作需要的顺序请求编号
filename 当前操作所在源代码的文件名
lineNumber 当前操作所在源代码的行数
备注:
_Check_return_ _CRTIMP size_t __cdecl _msize(_In_ void * _Memory);
翻译自(MSDN http://msdn.microsoft.com/zh-cn/library/820k4tb8(VS.90).aspx)