Reactos
1//
2// recalloc.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Implementation of _recalloc()
7//
8#include <corecrt_internal.h>
9#include <malloc.h>
10#include <string.h>
11
12
13
14// This function provides the logic for the _recalloc() function. It is called
15// only in the Release CRT (in the Debug CRT, the debug heap has its own
16// implementation of _recalloc()).
17//
18// This function must be marked noinline, otherwise recalloc and
19// _recalloc_base will have identical COMDATs, and the linker will fold
20// them when calling one from the CRT. This is necessary because recalloc
21// needs to support users patching in custom implementations.
22extern "C" __declspec(noinline) void* __cdecl _recalloc_base(
23 void* const block,
24 size_t const count,
25 size_t const size
26 )
27{
28 // Ensure that (count * size) does not overflow
29 _VALIDATE_RETURN_NOEXC(count == 0 || (_HEAP_MAXREQ / count) >= size, ENOMEM, nullptr);
30
31 size_t const old_block_size = block != nullptr ? _msize_base(block) : 0;
32 size_t const new_block_size = count * size;
33
34 void* const new_block = _realloc_base(block, new_block_size);
35
36 // If the reallocation succeeded and the new block is larger, zero-fill the
37 // new bytes:
38 if (new_block != nullptr && old_block_size < new_block_size)
39 {
40 memset(static_cast<char*>(new_block) + old_block_size, 0, new_block_size - old_block_size);
41 }
42
43 return new_block;
44}
45
46// Reallocates a block of memory in the heap.
47//
48// This function reallocates the block pointed to by 'block' such that it is
49// 'count * size' bytes in size. The new size may be either greater or less
50// than the original size of the block. If the new size is greater than the
51// original size, the new bytes are zero-filled. This function shares its
52// implementation with the realloc() function; consult the comments of that
53// function for more information about the implementation.
54//
55// This function supports patching and therefore must be marked noinline.
56// Both _recalloc_dbg and _recalloc_base must also be marked noinline
57// to prevent identical COMDAT folding from substituting calls to _recalloc
58// with either other function or vice versa.
59extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _recalloc(
60 void* const block,
61 size_t const count,
62 size_t const size
63 )
64{
65 #ifdef _DEBUG
66 return _recalloc_dbg(block, count, size, _NORMAL_BLOCK, nullptr, 0);
67 #else
68 return _recalloc_base(block, count, size);
69 #endif
70}