我之前读到过这个问题,但无法在MSDN或其他任何网站上找到有关crt更改的信息。
我认为在VS2012的VC++版本中,msvcrt已经以一种不再使用私有堆进行分配而是改用进程堆的方式进行了更改。
据我所知,它针对的是在多个库中分配内存并静态链接到crt的问题,以及在另一个库中释放它所分配的内存的问题。
在我看来,这是一项重大变革,我想知道为什么我找不到任何提到它的文档。要么就是我自己编造的(我觉得不太可能,因为我之前和同事讨论过这个话题)。
我之前读到过这个问题,但无法在MSDN或其他任何网站上找到有关crt更改的信息。
我认为在VS2012的VC++版本中,msvcrt已经以一种不再使用私有堆进行分配而是改用进程堆的方式进行了更改。
据我所知,它针对的是在多个库中分配内存并静态链接到crt的问题,以及在另一个库中释放它所分配的内存的问题。
在我看来,这是一项重大变革,我想知道为什么我找不到任何提到它的文档。要么就是我自己编造的(我觉得不太可能,因为我之前和同事讨论过这个话题)。
没错。 这个更改是在 VS2012 中进行的,似乎是未来的行为。 您可以在 CRT 的源代码中找到相关代码,在 vc/crt/src/heapinit.c 源代码文件中找到:
int __cdecl _heap_init (void)
{
if ( (_crtheap = GetProcessHeap()) == NULL )
return 0;
return 1;
}
之前的版本在这里使用HeapCreate(),同时还有VS5和VS6的兼容性处理。由于这不是公开宣传的,因此其确切原因并不那么清楚。VS2012的一个重要细节是,它最初发布时没有XP支持。这就免去了必须显式启用低碎片堆的要求。LFH已自动启用于Vista及以上版本,因此默认进程堆已经很好了。
使用默认进程堆的一个非常大的优点是解决了DLL拥有自己的CRT副本并因此使用自己的分配器所带来的非常严重的问题。当一个DLL需要释放另一个DLL分配的内存时,这通常会导致非常糟糕的结果。只要重新构建DLL以针对较新版本的CRT,现在就不存在这样的问题了,因为它们自动使用完全相同的堆,因此在模块边界传递指针是安全的。
也有一些相关的担忧。我不确定更新1中发生了什么,更新1是带回XP支持的更新。假设CRT源代码是准确的(看起来是这样),那么你的程序很可能在XP上运行时未启用LFH。
此外,还存在潜在的安全问题,因为winapi也使用默认进程堆。因此,恶意软件现在可能利用你的代码中的缓冲区溢出漏洞并达到winapi缓冲区。如果您之前已对您的代码进行了安全分析和/或模糊测试,则应重新进行这些测试。我假设Microsoft在强烈依赖其安全CRT实现以避免安全问题,但这只是一个猜测。希望James McNellis能够提供更深入的见解。