1 // 2 // malloc_base.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Implementation of _malloc_base(). This is defined in a different source file 7 // from the malloc() function to allow malloc() to be replaced by the user. 8 // 9 #include <corecrt_internal.h> 10 #include <malloc.h> 11 #include <new.h> 12 13 14 15 // This function implements the logic of malloc(). It is called directly by the 16 // malloc() function in the Release CRT and is called by the debug heap in the 17 // Debug CRT. 18 // 19 // This function must be marked noinline, otherwise malloc and 20 // _malloc_base will have identical COMDATs, and the linker will fold 21 // them when calling one from the CRT. This is necessary because malloc 22 // needs to support users patching in custom implementations. 23 extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _malloc_base(size_t const size) 24 { 25 // Ensure that the requested size is not too large: 26 _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr); 27 28 // Ensure we request an allocation of at least one byte: 29 size_t const actual_size = size == 0 ? 1 : size; 30 31 for (;;) 32 { 33 void* const block = HeapAlloc(__acrt_heap, 0, actual_size); 34 if (block) 35 return block; 36 37 // Otherwise, see if we need to call the new handler, and if so call it. 38 // If the new handler fails, just return nullptr: 39 if (_query_new_mode() == 0 || !_callnewh(actual_size)) 40 { 41 errno = ENOMEM; 42 return nullptr; 43 } 44 45 // The new handler was successful; try to allocate again... 46 } 47 } 48