Files
UnrealEngineUWP/Engine/Source/ThirdParty/mimalloc/docs/group__malloc.html
danny couture e6f54c17c4 Update mimalloc to version 2.0.0-2762784 for HUGE memory usage improvement in editor workloads
This version of mimalloc is very efficient at distributing threaded allocations in a way that maintains
    locality which in turn improve the amount of memory that we're able to send back to the system
    after heavily multithreaded workloads. This also improves performance as less page fault and cache misses
    are expected coming from more densily packed allocations.

    mimalloc v1 seemed to waste more memory because of its commit size being larger than TBB.
    However, its allocation patterns was already way tigther than TBB but for it to become apparent, you had
    to activate the "page_reset" and "reset_decommits" options, which came at a performance loss.

    mimalloc v2 offers both better locality and by default will more agressively decommit memory with
    only minor performance loss in some cases and performance gain in many.

    Given the advantages of mimalloc v2 compared to Intel TBB, we should probably consider it
    as our next default allocator for the editor.

 - All tests performed on AMD TR 3970X with 256GB RAM
   - Loading FramingCameraTest map on special project with -ddc=cold and waiting until every asset is built
     - 699s @ 32GB for tbb malloc
     - 655s @ 37GB for mimalloc v1
     - 757s @ 12GB for mimalloc v1 + page_reset and reset_decommits
     - 604s @ 15GB for mimalloc v2
   - Loading P_World on Reverb -ddc=cold and waiting until every asset is built
     - 2372s @ 71GB for tbb malloc
     - 2587s @ 75GB for mimalloc v1
     - 3212s @ 34GB for mimalloc v1 + page_reset and reset_decommits
     - 2503s @ 37GB for mimalloc v2
   - Loading P_Construct_WP on special project with -ddc=cold and waiting until every asset is built
     - 6404s @ 56GB for tbb malloc
     - 6640s @ 37GB for mimalloc v2
   - Loading Apollo_Terrain on FortniteGame with -ddc=cold and waiting until every asset is built
     - 751s @ 33GB for tbb malloc
     - 744s @ 25GB for mimalloc v2
    - Cooking FramingCameraTest map on special project with a warmed-up DDC
     - 379s @ 34GB for tbb malloc
     - 367s @ 29GB for mimalloc v2

#rb Brandon.Dawson, Yuriy.ODonnell, Stefan.Boberg

[CL 15859558 by danny couture in ue5-main branch]
2021-03-30 06:38:15 -04:00

645 lines
33 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.15"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>mi-malloc: Basic Allocation</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(initResizable);
/* @license-end */</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">mi-malloc
&#160;<span id="projectnumber">1.6</span>
</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.15 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('group__malloc.html','');});
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="summary">
<a href="#func-members">Functions</a> </div>
<div class="headertitle">
<div class="title">Basic Allocation</div> </div>
</div><!--header-->
<div class="contents">
<p>The basic allocation interface.
<a href="#details">More...</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:gaf2c7b89c327d1f60f59e68b9ea644d95"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95">mi_free</a> (void *p)</td></tr>
<tr class="memdesc:gaf2c7b89c327d1f60f59e68b9ea644d95"><td class="mdescLeft">&#160;</td><td class="mdescRight">Free previously allocated memory. <a href="#gaf2c7b89c327d1f60f59e68b9ea644d95">More...</a><br /></td></tr>
<tr class="separator:gaf2c7b89c327d1f60f59e68b9ea644d95"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga3406e8b168bc74c8637b11571a6da83a"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a">mi_malloc</a> (size_t size)</td></tr>
<tr class="memdesc:ga3406e8b168bc74c8637b11571a6da83a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocate <em>size</em> bytes. <a href="#ga3406e8b168bc74c8637b11571a6da83a">More...</a><br /></td></tr>
<tr class="separator:ga3406e8b168bc74c8637b11571a6da83a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gafdd9d8bb2986e668ba9884f28af38000"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000">mi_zalloc</a> (size_t size)</td></tr>
<tr class="memdesc:gafdd9d8bb2986e668ba9884f28af38000"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocate zero-initialized <code>size</code> bytes. <a href="#gafdd9d8bb2986e668ba9884f28af38000">More...</a><br /></td></tr>
<tr class="separator:gafdd9d8bb2986e668ba9884f28af38000"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga97fedb4f7107c592fd7f0f0a8949a57d"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d">mi_calloc</a> (size_t count, size_t size)</td></tr>
<tr class="memdesc:ga97fedb4f7107c592fd7f0f0a8949a57d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocate zero-initialized <em>count</em> elements of <em>size</em> bytes. <a href="#ga97fedb4f7107c592fd7f0f0a8949a57d">More...</a><br /></td></tr>
<tr class="separator:ga97fedb4f7107c592fd7f0f0a8949a57d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaf11eb497da57bdfb2de65eb191c69db6"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6">mi_realloc</a> (void *p, size_t newsize)</td></tr>
<tr class="memdesc:gaf11eb497da57bdfb2de65eb191c69db6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Re-allocate memory to <em>newsize</em> bytes. <a href="#gaf11eb497da57bdfb2de65eb191c69db6">More...</a><br /></td></tr>
<tr class="separator:gaf11eb497da57bdfb2de65eb191c69db6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga23a0fbb452b5dce8e31fab1a1958cacc"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc">mi_recalloc</a> (void *p, size_t count, size_t size)</td></tr>
<tr class="memdesc:ga23a0fbb452b5dce8e31fab1a1958cacc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Re-allocate memory to <em>count</em> elements of <em>size</em> bytes, with extra memory initialized to zero. <a href="#ga23a0fbb452b5dce8e31fab1a1958cacc">More...</a><br /></td></tr>
<tr class="separator:ga23a0fbb452b5dce8e31fab1a1958cacc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaaee66a1d483c3e28f585525fb96707e4"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4">mi_expand</a> (void *p, size_t newsize)</td></tr>
<tr class="memdesc:gaaee66a1d483c3e28f585525fb96707e4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Try to re-allocate memory to <em>newsize</em> bytes <em>in place</em>. <a href="#gaaee66a1d483c3e28f585525fb96707e4">More...</a><br /></td></tr>
<tr class="separator:gaaee66a1d483c3e28f585525fb96707e4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga0b05e2bf0f73e7401ae08597ff782ac6"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6">mi_mallocn</a> (size_t count, size_t size)</td></tr>
<tr class="memdesc:ga0b05e2bf0f73e7401ae08597ff782ac6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocate <em>count</em> elements of <em>size</em> bytes. <a href="#ga0b05e2bf0f73e7401ae08597ff782ac6">More...</a><br /></td></tr>
<tr class="separator:ga0b05e2bf0f73e7401ae08597ff782ac6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga61d57b4144ba24fba5c1e9b956d13853"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853">mi_reallocn</a> (void *p, size_t count, size_t size)</td></tr>
<tr class="memdesc:ga61d57b4144ba24fba5c1e9b956d13853"><td class="mdescLeft">&#160;</td><td class="mdescRight">Re-allocate memory to <em>count</em> elements of <em>size</em> bytes. <a href="#ga61d57b4144ba24fba5c1e9b956d13853">More...</a><br /></td></tr>
<tr class="separator:ga61d57b4144ba24fba5c1e9b956d13853"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gafe68ac7c5e24a65cd55c9d6b152211a0"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0">mi_reallocf</a> (void *p, size_t newsize)</td></tr>
<tr class="memdesc:gafe68ac7c5e24a65cd55c9d6b152211a0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Re-allocate memory to <em>newsize</em> bytes,. <a href="#gafe68ac7c5e24a65cd55c9d6b152211a0">More...</a><br /></td></tr>
<tr class="separator:gafe68ac7c5e24a65cd55c9d6b152211a0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gac7cffe13f1f458ed16789488bf92b9b2"><td class="memItemLeft" align="right" valign="top">char *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2">mi_strdup</a> (const char *s)</td></tr>
<tr class="memdesc:gac7cffe13f1f458ed16789488bf92b9b2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocate and duplicate a string. <a href="#gac7cffe13f1f458ed16789488bf92b9b2">More...</a><br /></td></tr>
<tr class="separator:gac7cffe13f1f458ed16789488bf92b9b2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaaabf971c2571891433477e2d21a35266"><td class="memItemLeft" align="right" valign="top">char *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaaabf971c2571891433477e2d21a35266">mi_strndup</a> (const char *s, size_t n)</td></tr>
<tr class="memdesc:gaaabf971c2571891433477e2d21a35266"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocate and duplicate a string up to <em>n</em> bytes. <a href="#gaaabf971c2571891433477e2d21a35266">More...</a><br /></td></tr>
<tr class="separator:gaaabf971c2571891433477e2d21a35266"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga08cec32dd5bbe7da91c78d19f1b5bebe"><td class="memItemLeft" align="right" valign="top">char *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe">mi_realpath</a> (const char *fname, char *resolved_name)</td></tr>
<tr class="memdesc:ga08cec32dd5bbe7da91c78d19f1b5bebe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Resolve a file path name. <a href="#ga08cec32dd5bbe7da91c78d19f1b5bebe">More...</a><br /></td></tr>
<tr class="separator:ga08cec32dd5bbe7da91c78d19f1b5bebe"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<p>The basic allocation interface. </p>
<h2 class="groupheader">Function Documentation</h2>
<a id="ga97fedb4f7107c592fd7f0f0a8949a57d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga97fedb4f7107c592fd7f0f0a8949a57d">&#9670;&nbsp;</a></span>mi_calloc()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_calloc </td>
<td>(</td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>count</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>size</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Allocate zero-initialized <em>count</em> elements of <em>size</em> bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">count</td><td>number of elements. </td></tr>
<tr><td class="paramname">size</td><td>size of each element. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>pointer to the allocated memory of <em>size*<em>count</em> bytes</em>, or <em>NULL</em> if either out of memory or when <code>count*size</code> overflows.</dd></dl>
<p>Returns a unique pointer if called with either <em>size</em> or <em>count</em> of 0. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000" title="Allocate zero-initialized size bytes.">mi_zalloc()</a> </dd></dl>
</div>
</div>
<a id="gaaee66a1d483c3e28f585525fb96707e4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gaaee66a1d483c3e28f585525fb96707e4">&#9670;&nbsp;</a></span>mi_expand()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_expand </td>
<td>(</td>
<td class="paramtype">void *&#160;</td>
<td class="paramname"><em>p</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>newsize</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Try to re-allocate memory to <em>newsize</em> bytes <em>in place</em>. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">p</td><td>pointer to previously allocated memory (or <em>NULL</em>). </td></tr>
<tr><td class="paramname">newsize</td><td>the new required size in bytes. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>pointer to the re-allocated memory of <em>newsize</em> bytes (always equal to <em>p</em>), or <em>NULL</em> if either out of memory or if the memory could not be expanded in place. If <em>NULL</em> is returned, the pointer <em>p</em> is not freed. Otherwise the original pointer is returned as the reallocated result since it fits in-place with the new size. If <em>newsize</em> is larger than the original <em>size</em> allocated for <em>p</em>, the bytes after <em>size</em> are uninitialized. </dd></dl>
</div>
</div>
<a id="gaf2c7b89c327d1f60f59e68b9ea644d95"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gaf2c7b89c327d1f60f59e68b9ea644d95">&#9670;&nbsp;</a></span>mi_free()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void mi_free </td>
<td>(</td>
<td class="paramtype">void *&#160;</td>
<td class="paramname"><em>p</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Free previously allocated memory. </p>
<p>The pointer <code>p</code> must have been allocated before (or be <em>NULL</em>). </p><dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">p</td><td>pointer to free, or <em>NULL</em>. </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="ga3406e8b168bc74c8637b11571a6da83a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga3406e8b168bc74c8637b11571a6da83a">&#9670;&nbsp;</a></span>mi_malloc()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_malloc </td>
<td>(</td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>size</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Allocate <em>size</em> bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">size</td><td>number of bytes to allocate. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>pointer to the allocated memory or <em>NULL</em> if out of memory. Returns a unique pointer if called with <em>size</em> 0. </dd></dl>
</div>
</div>
<a id="ga0b05e2bf0f73e7401ae08597ff782ac6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga0b05e2bf0f73e7401ae08597ff782ac6">&#9670;&nbsp;</a></span>mi_mallocn()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_mallocn </td>
<td>(</td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>count</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>size</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Allocate <em>count</em> elements of <em>size</em> bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">count</td><td>The number of elements. </td></tr>
<tr><td class="paramname">size</td><td>The size of each element. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A pointer to a block of <em>count</em> * <em>size</em> bytes, or <em>NULL</em> if out of memory or if <em>count</em> * <em>size</em> overflows.</dd></dl>
<p>If there is no overflow, it behaves exactly like <code>mi_malloc(p,count*size)</code>. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d" title="Allocate zero-initialized count elements of size bytes.">mi_calloc()</a> </dd>
<dd>
mi_zallocn() </dd></dl>
</div>
</div>
<a id="gaf11eb497da57bdfb2de65eb191c69db6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gaf11eb497da57bdfb2de65eb191c69db6">&#9670;&nbsp;</a></span>mi_realloc()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_realloc </td>
<td>(</td>
<td class="paramtype">void *&#160;</td>
<td class="paramname"><em>p</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>newsize</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Re-allocate memory to <em>newsize</em> bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">p</td><td>pointer to previously allocated memory (or <em>NULL</em>). </td></tr>
<tr><td class="paramname">newsize</td><td>the new required size in bytes. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>pointer to the re-allocated memory of <em>newsize</em> bytes, or <em>NULL</em> if out of memory. If <em>NULL</em> is returned, the pointer <em>p</em> is not freed. Otherwise the original pointer is either freed or returned as the reallocated result (in case it fits in-place with the new size). If the pointer <em>p</em> is <em>NULL</em>, it behaves as <em>mi_malloc</em>(<em>newsize</em>). If <em>newsize</em> is larger than the original <em>size</em> allocated for <em>p</em>, the bytes after <em>size</em> are uninitialized. </dd></dl>
</div>
</div>
<a id="gafe68ac7c5e24a65cd55c9d6b152211a0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gafe68ac7c5e24a65cd55c9d6b152211a0">&#9670;&nbsp;</a></span>mi_reallocf()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_reallocf </td>
<td>(</td>
<td class="paramtype">void *&#160;</td>
<td class="paramname"><em>p</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>newsize</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Re-allocate memory to <em>newsize</em> bytes,. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">p</td><td>pointer to previously allocated memory (or <em>NULL</em>). </td></tr>
<tr><td class="paramname">newsize</td><td>the new required size in bytes. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>pointer to the re-allocated memory of <em>newsize</em> bytes, or <em>NULL</em> if out of memory.</dd></dl>
<p>In contrast to <a class="el" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6" title="Re-allocate memory to newsize bytes.">mi_realloc()</a>, if <em>NULL</em> is returned, the original pointer <em>p</em> is freed (if it was not <em>NULL</em> itself). Otherwise the original pointer is either freed or returned as the reallocated result (in case it fits in-place with the new size). If the pointer <em>p</em> is <em>NULL</em>, it behaves as <em>mi_malloc</em>(<em>newsize</em>). If <em>newsize</em> is larger than the original <em>size</em> allocated for <em>p</em>, the bytes after <em>size</em> are uninitialized.</p>
<dl class="section see"><dt>See also</dt><dd><a href="https://www.freebsd.org/cgi/man.cgi?query=reallocf">reallocf</a> (on BSD) </dd></dl>
</div>
</div>
<a id="ga61d57b4144ba24fba5c1e9b956d13853"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga61d57b4144ba24fba5c1e9b956d13853">&#9670;&nbsp;</a></span>mi_reallocn()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_reallocn </td>
<td>(</td>
<td class="paramtype">void *&#160;</td>
<td class="paramname"><em>p</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>count</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>size</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Re-allocate memory to <em>count</em> elements of <em>size</em> bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">p</td><td>Pointer to a previously allocated block (or <em>NULL</em>). </td></tr>
<tr><td class="paramname">count</td><td>The number of elements. </td></tr>
<tr><td class="paramname">size</td><td>The size of each element. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A pointer to a re-allocated block of <em>count</em> * <em>size</em> bytes, or <em>NULL</em> if out of memory or if <em>count</em> * <em>size</em> overflows.</dd></dl>
<p>If there is no overflow, it behaves exactly like <code>mi_realloc(p,count*size)</code>. </p><dl class="section see"><dt>See also</dt><dd><a href="http://man.openbsd.org/reallocarray">reallocarray()</a> (on BSD) </dd></dl>
</div>
</div>
<a id="ga08cec32dd5bbe7da91c78d19f1b5bebe"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga08cec32dd5bbe7da91c78d19f1b5bebe">&#9670;&nbsp;</a></span>mi_realpath()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">char* mi_realpath </td>
<td>(</td>
<td class="paramtype">const char *&#160;</td>
<td class="paramname"><em>fname</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">char *&#160;</td>
<td class="paramname"><em>resolved_name</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Resolve a file path name. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">fname</td><td>File name. </td></tr>
<tr><td class="paramname">resolved_name</td><td>Should be <em>NULL</em> (but can also point to a buffer of at least <em>PATH_MAX</em> bytes). </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>If successful a pointer to the resolved absolute file name, or <em>NULL</em> on failure (with <em>errno</em> set to the error code).</dd></dl>
<p>If <em>resolved_name</em> was <em>NULL</em>, the returned result should be freed with <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a>.</p>
<p>Replacement for the standard <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html">realpath()</a> such that <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a> can be used on the returned result (if <em>resolved_name</em> was <em>NULL</em>). </p>
</div>
</div>
<a id="ga23a0fbb452b5dce8e31fab1a1958cacc"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga23a0fbb452b5dce8e31fab1a1958cacc">&#9670;&nbsp;</a></span>mi_recalloc()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void * mi_recalloc </td>
<td>(</td>
<td class="paramtype">void *&#160;</td>
<td class="paramname"><em>p</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>count</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>size</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Re-allocate memory to <em>count</em> elements of <em>size</em> bytes, with extra memory initialized to zero. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">p</td><td>Pointer to a previously allocated block (or <em>NULL</em>). </td></tr>
<tr><td class="paramname">count</td><td>The number of elements. </td></tr>
<tr><td class="paramname">size</td><td>The size of each element. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A pointer to a re-allocated block of <em>count</em> * <em>size</em> bytes, or <em>NULL</em> if out of memory or if <em>count</em> * <em>size</em> overflows.</dd></dl>
<p>If there is no overflow, it behaves exactly like <code>mi_rezalloc(p,count*size)</code>. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853" title="Re-allocate memory to count elements of size bytes.">mi_reallocn()</a> </dd>
<dd>
<a href="http://man.openbsd.org/reallocarray">recallocarray()</a> (on BSD). </dd></dl>
</div>
</div>
<a id="gac7cffe13f1f458ed16789488bf92b9b2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gac7cffe13f1f458ed16789488bf92b9b2">&#9670;&nbsp;</a></span>mi_strdup()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">char* mi_strdup </td>
<td>(</td>
<td class="paramtype">const char *&#160;</td>
<td class="paramname"><em>s</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Allocate and duplicate a string. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">s</td><td>string to duplicate (or <em>NULL</em>). </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>a pointer to newly allocated memory initialized to string <em>s</em>, or <em>NULL</em> if either out of memory or if <em>s</em> is <em>NULL</em>.</dd></dl>
<p>Replacement for the standard <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html">strdup()</a> such that <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a> can be used on the returned result. </p>
</div>
</div>
<a id="gaaabf971c2571891433477e2d21a35266"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gaaabf971c2571891433477e2d21a35266">&#9670;&nbsp;</a></span>mi_strndup()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">char* mi_strndup </td>
<td>(</td>
<td class="paramtype">const char *&#160;</td>
<td class="paramname"><em>s</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>n</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Allocate and duplicate a string up to <em>n</em> bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">s</td><td>string to duplicate (or <em>NULL</em>). </td></tr>
<tr><td class="paramname">n</td><td>maximum number of bytes to copy (excluding the terminating zero). </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>a pointer to newly allocated memory initialized to string <em>s</em> up to the first <em>n</em> bytes (and always zero terminated), or <em>NULL</em> if either out of memory or if <em>s</em> is <em>NULL</em>.</dd></dl>
<p>Replacement for the standard <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html">strndup()</a> such that <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a> can be used on the returned result. </p>
</div>
</div>
<a id="gafdd9d8bb2986e668ba9884f28af38000"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gafdd9d8bb2986e668ba9884f28af38000">&#9670;&nbsp;</a></span>mi_zalloc()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void* mi_zalloc </td>
<td>(</td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>size</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Allocate zero-initialized <code>size</code> bytes. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">size</td><td>The size in bytes. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Pointer to newly allocated zero initialized memory, or <em>NULL</em> if out of memory. </dd></dl>
</div>
</div>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.15 </li>
</ul>
</div>
</body>
</html>