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