Reactos
at master 53 lines 1.7 kB view raw
1// 2// calloc_base.cpp 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// Implementation of _calloc_base(). This is defined in a different source file 7// from the calloc() function to allow calloc() to be replaced by the user. 8// 9#include <corecrt_internal.h> 10#include <malloc.h> 11#include <new.h> 12 13// This function implements the logic of calloc(). 14// 15// This function must be marked noinline, otherwise calloc and 16// _calloc_base will have identical COMDATs, and the linker will fold 17// them when calling one from the CRT. This is necessary because calloc 18// needs to support users patching in custom implementations. 19extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _calloc_base( 20 size_t const count, 21 size_t const size 22 ) 23{ 24 // Ensure that (count * size) does not overflow 25 _VALIDATE_RETURN_NOEXC(count == 0 || (_HEAP_MAXREQ / count) >= size, ENOMEM, nullptr); 26 27 // Ensure that we allocate a nonzero block size: 28 size_t const requested_block_size = count * size; 29 size_t const actual_block_size = requested_block_size == 0 30 ? 1 31 : requested_block_size; 32 33 for (;;) 34 { 35 void* const block = HeapAlloc(__acrt_heap, HEAP_ZERO_MEMORY, actual_block_size); 36 37 // If allocation succeeded, return the pointer to the new block: 38 if (block) 39 { 40 return block; 41 } 42 43 // Otherwise, see if we need to call the new handler, and if so call it. 44 // If the new handler fails, just return nullptr: 45 if (_query_new_mode() == 0 || !_callnewh(actual_block_size)) 46 { 47 errno = ENOMEM; 48 return nullptr; 49 } 50 51 // The new handler was successful; try to allocate aagain... 52 } 53}