Reactos
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.
23extern "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}