7

I've read about that some time ago but am unable to locate the change to the crt on msdn or anywhere else in the web.

I think the msvcrt has been changed in the VC++ release of VS2012 in a way that it no longer uses the private heap for allocations and uses process heap instead.

Afaik it targeted issues of memory allocated in multiple libs which link statically against a crt and the subsequent release of memory in another lib where it was allocated.

This is a major change in my view and I wonder why I cannot find any doc mentioning it. Either that or I made it up (which I doubt as I've discussed the topic with colleagues some time ago)

Samuel
  • 6,126
  • 35
  • 70
  • 1
    Does the CRT source still ships with VS? Mine isn't handy to check, but I thought it still did. if so, it'd be hard to beat that reference. – WhozCraig Feb 07 '14 at 10:37
  • 1
    Since it now uses GetProcessHeap does this mean mixing static and dynamic CRT's of the same VS version is now supported? – paulm Feb 07 '14 at 13:26
  • @paulm, afaik this is indeed the implication. – Samuel Feb 07 '14 at 13:28

1 Answers1

15

That is correct. This change was made in VS2012 and appears to be the behavior going forward. You can see the relevant code in the source code you have for the CRT, find it in the vc/crt/src/heapinit.c source code file:

int __cdecl _heap_init (void)
{
        if ( (_crtheap = GetProcessHeap()) == NULL )
            return 0;

        return 1;
}

Previous versions used HeapCreate() here, also with VS5 and VS6 legacy hacks. This is not well publicized so the exact reasoning behind it is not that clear. One important detail of VS2012 is that it initially shipped without XP support. Which dropped the requirement to explicitly having to enable the low-fragmentation heap. LFH is automatically enabled on Vista and up so the default process heap is already good as-is.

A very major advantage of using the default process heap is that it solves the very nasty problems with DLLs having their own copy of the CRT and thus using their own allocators. This traditionally ended up very poorly when one DLL needed to release the memory allocated by another. No such problems anymore, as long as DLLs are rebuilt to target the later version of the CRT, they now automatically use the exact same heap so passing pointers across the module boundaries is safe.

Some concerns are valid as well. It is not clear to me what happened in Update 1, the one that brought back XP support. Assuming the CRT source is accurate (it looks like it is) then there are good odds that your program is running without the LFH enabled on XP.

And there's a possible security concern, the default process heap is also used by the winapi. So it is now technically possible for malware to hijack a buffer overflow bug in your code and reach winapi buffers. If you've previously subjected your code to a security analysis and/or fuzz testing then you should redo this. I assume that Microsoft is strongly relying on their secure CRT implementation to avoid the security issues but that's a blind guess. Hopefully James McNellis will be available to give deeper insight.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Great explanation, and thank you for the additional hinting of XP and security. Now that it is confirmed I concentrate to locate the msdn article about it. – Samuel Feb 07 '14 at 11:20
  • Pretty sure that MSDN doesn't mention this anywhere. – Hans Passant Feb 07 '14 at 11:24
  • I found an article targeted for VS2012 which seem entirely ignore the implication of process heap on the crt: http://msdn.microsoft.com/en-us/library/ms235460%28v=vs.110%29.aspx as it still points out that crossing dll boundaries is still an issue. This confuses me. – Samuel Feb 07 '14 at 11:27
  • 1
    Yes, it is very old. Note how it talks about versions 4.1 and 5.0, that's three dog-lives ago. The concerns about passing CRT state across modules (things like locale, errno, etc) are still valid. – Hans Passant Feb 07 '14 at 11:36
  • @Samuel: this all depends how much administration the crt adds to the Windows heap. In _DEBUG code this is significant with its leaking reporting capabilities and border checking; in release mode it seems that allocations are just forwarded to HeapAlloc. Still it is better to just always use the same shared crt library on your modules. – gast128 Feb 07 '17 at 16:04