Conflict with _CRTDBG_MAP_ALLOC (Visual Studio)

I tried to include the Juce header in one of my projects, but I’m getting caught up on juce_HeapBlock.h. The problem is that I define _CRTDBG_MAP_ALLOC, which turns malloc() into a macro, causing juce_HeapBlock.h to produce compile errors. I could turn off this #define but then I would lose standard-library level leak checking for a lot of existing code that uses malloc().

I don’t really see a way around it other than renaming the methods in juce::HeapBlock to not conflict with standard C library function names.

1 Like

#undef before including juce ?

That is the same as just turning off _CRTDBG_MAP_ALLOC, which means no debug leak checking for the standard library calls.

You could undef it before including juce, and then re-def it afterwards?

Okay there seems to be some misunderstanding of how this thing works. What you do is #define _CRTDBG_MAP_ALLOC before including standard headers like <memory.h>. This causes those header files to create macros for malloc() that generate calls to _dbg_malloc() and what not, with the file and line number as parameters for leak reporting.

Once you define _CRTDBG_MAP_ALLOC and include <memory.h>, #undef of _CRTDBG_MAP_ALLOC doesn’t do anything. You could #undef malloc but then redefining it would be a hassle.

I’m amazed that no one else has run into this problem…am I the only one who uses the Visual Studio debug heap features??!

I’ve always used the debug allocator, but only by calling the _dbg_malloc directly. #defining malloc is just asking for trouble!

I hear you but thats how MSVC implemented it. Maybe we can rename your functions, i.e. HeapBlock::jmalloc() ?

Sorry, I ain’t compromising my lovely code because of MFC’s stoopid design!

Did you know there’s a #pragma push_macro/pop_macro? You could use those either side of juce to save and restore all the malloc macros.

That is a good solution, I will use it.

I ran into the exact same problem, thanks! Took me a little while to find the macros so I thought I’d share. I also redefined ‘new’ to give trace information.

EDIT: Redefining ‘new’ causes problems as soon as you overload the ‘new’ operator so I removed it from the code below.

[code]#if _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#pragma push_macro("calloc")
#pragma push_macro("free")
#pragma push_macro("malloc")
#pragma push_macro("realloc")
#pragma push_macro("_recalloc")
#pragma push_macro("_aligned_free")
#pragma push_macro("_aligned_malloc")
#pragma push_macro("_aligned_offset_malloc")
#pragma push_macro("_aligned_realloc")
#pragma push_macro("_aligned_recalloc")
#pragma push_macro("_aligned_offset_realloc")
#pragma push_macro("_aligned_offset_recalloc")
#pragma push_macro("_aligned_msize")

#undef calloc
#undef free
#undef malloc
#undef realloc
#undef _recalloc
#undef _aligned_free
#undef _aligned_malloc
#undef _aligned_offset_malloc
#undef _aligned_realloc
#undef _aligned_recalloc
#undef _aligned_offset_realloc
#undef _aligned_offset_recalloc
#undef _aligned_msize

#include "juce.h"

#pragma pop_macro("_aligned_msize")
#pragma pop_macro("_aligned_offset_recalloc")
#pragma pop_macro("_aligned_offset_realloc")
#pragma pop_macro("_aligned_recalloc")
#pragma pop_macro("_aligned_realloc")
#pragma pop_macro("_aligned_offset_malloc")
#pragma pop_macro("_aligned_malloc")
#pragma pop_macro("_aligned_free")
#pragma pop_macro("_recalloc")
#pragma pop_macro("realloc")
#pragma pop_macro("malloc")
#pragma pop_macro("free")
#pragma pop_macro("calloc")

#else
#include “juce.h”
#endif[/code]

Hi there,
I want to reply to this post because it is real that using reserved keyword in JUCE is quite a bad idea.
For example, I am in the case that I have a memory leak that pop out from nowhere using “Detected memory leaks !” scheme and I cannot use _CRTDBG_MAP_ALLOC flag to know from where bug starts.
In those (rare) cases, the use of reserved keywords in JUCE is a real pain in the ass.
For future release, could you consider modifying this kind of habit please ?
Best regards.

P.S. : that is not a complain or something like that, I do not want to make you sad or angry, I just point out a fact that can be really difficult to pass through.

Just hit this today. Kind of a bummer. Yes, macroing malloc is pretty awful, but you can see why they did it.

Why not have HeapBlock::allocate, reallocate, and deallocate? (Like std::allocator)

1 Like

I guess that with this solution it is not possible to track calls to malloc etc. from within juce code, is that correct?

1 Like

Ran into this today as well… I guess it would be more under my influence to make Juce turn on this point than Microsoft (though I totally understand and agree with you, Jules). So add my thumb up for a Juce-side change request (FWIW).

1 Like

Every few years, an unlucky programmer hits this issue. Today, I was the unlucky one.

1 Like

+1

Thanks to cjuillard, but that didn’ help in my case.

If the problem is a name clash of “HeapBlock::malloc”, etc. with the standard library names, when they get re-#defined via macros and the main objection is the ugliness of renaming it to something like “HeapBlock::jmalloc”, then I would indeed also (like tayholliday suggested) say that renaming it to “HeapBlock::allocate” would be a good solution. To be honest, “malloc” is not a particularly nice function name to begin with anyway (unless, maybe, the intention is to document that it calls std::malloc internally, which it does - but that actually seems to be an implementation detail that shouldn’t matter to the caller). The name “malloc” is just an historic artifact of the C-language and “allocate” is arguably more descriptive. I do care a lot about code aesthetics, too - but I also happen to think that descriptive names are aesthetically preferable over historic names. And I think, one could find better names for the other problematic functions, too: malloc → allocate, free → deallocate, realloc → reallocate, calloc → allocateAndInit, for example. Renaming could become a double-win instead of a different tradeoff.

3 Likes

Sounds good. I think the names that you wrote which @tayholliday suggested are better. In the case of calloc I think that the name allocateAndInit is especially better since the name directly makes you know what the method does. I can make the change, but it would be good if someone from juce dev team say that they will approve the change.

@reuk Could you please take a look and consider this? Given that juce does not have extensive tests that can catch allocations in the wrong place I think it is a good change since it enables users of your library to implement allocation checks in both their and juce code. While it is unusual with such mistakes from juce side they do happen.

1 Like