mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
211 lines
16 KiB
HTML
211 lines
16 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=11"/>
|
||
<meta name="generator" content="Doxygen 1.16.1"/>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||
<title>HDF5: Freeing Memory Allocated by the HDF5 Library</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="navtreedata.js"></script>
|
||
<script type="text/javascript" src="navtree.js"></script>
|
||
<script type="text/javascript" src="cookie.js"></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">
|
||
$(function() { init_search(); });
|
||
</script>
|
||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||
<link href="hdf5doxy.css" rel="stylesheet" type="text/css"/>
|
||
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
|
||
<link href="hdf5doxy.css" rel="stylesheet" type="text/css">
|
||
<script type="text/javascript" src="hdf5_navtree_hacks.js"></script>
|
||
<div style="background:#FFDDDD;font-size:120%;text-align:center;margin:0;padding:5px">Help us improve by taking our short survey: <a href="https://www.hdfgroup.org/website-survey/">https://www.hdfgroup.org/website-survey/</a></div>
|
||
<!-- ... other metadata & script includes ... -->
|
||
<script type="text/javascript" src="doxygen-awesome-tabs.js"></script>
|
||
<script type="text/javascript">
|
||
DoxygenAwesomeTabs.init()
|
||
</script>
|
||
<!-- Google tag (gtag.js) -->
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-57FMZK4S7X"></script>
|
||
<script>
|
||
window.dataLayer = window.dataLayer || [];
|
||
function gtag(){dataLayer.push(arguments);}
|
||
gtag('js', new Date());
|
||
gtag('config', 'G-57FMZK4S7X');
|
||
</script>
|
||
</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 id="projectrow">
|
||
<td id="projectlogo"><img alt="Logo" src="HDFG-logo.png"/></td>
|
||
<td id="projectalign">
|
||
<div id="projectname">HDF5<span id="projectnumber"> Last Updated on 2026-09-02</span>
|
||
</div>
|
||
<div id="projectbrief">The HDF5 Field Guide</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<!-- end header part -->
|
||
<!-- Generated by Doxygen 1.16.1 -->
|
||
<script type="text/javascript">
|
||
var searchBox = new SearchBox("searchBox", "search/",'.html');
|
||
</script>
|
||
<script type="text/javascript">
|
||
$(function() { codefold.init(); });
|
||
</script>
|
||
<div id="main-nav">
|
||
<div id="navrow1" class="tabs">
|
||
<ul class="tablist">
|
||
<li><a href="index.html"><span>Main Page</span></a></li>
|
||
<li><a href="_getting_started.html"><span>Getting started</span></a></li>
|
||
<li><a href="_u_g.html"><span>User Guide</span></a></li>
|
||
<li><a href="_r_m.html"><span>Reference Manual</span></a></li>
|
||
<li><a href="_cookbook.html"><span>Cookbook</span></a></li>
|
||
<li><a href="_t_n.html"><span>Technical Notes</span></a></li>
|
||
<li><a href="_r_f_c.html"><span>RFCs</span></a></li>
|
||
<li><a href="_s_p_e_c.html"><span>Specifications</span></a></li>
|
||
<li><a href="_g_l_s.html"><span>Glossary</span></a></li>
|
||
<li><a href="_f_t_s.html"><span>Full-Text Search</span></a></li>
|
||
<li><a href="_about.html"><span>About</span></a></li>
|
||
<li>
|
||
<div id="MSearchBox" class="MSearchBoxInactive">
|
||
<span class="left">
|
||
<span id="MSearchSelect" class="search-icon" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()"><span class="search-icon-dropdown"></span></span>
|
||
<input type="text" id="MSearchField" value="" placeholder="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()"><div id="MSearchCloseImg" class="close-icon"></div></a>
|
||
</span>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div><!-- main-nav -->
|
||
</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">
|
||
$(function(){initNavTree('freeing_memory.html','',''); });
|
||
</script>
|
||
<div id="container">
|
||
<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">
|
||
<div id="MSearchResults">
|
||
<div class="SRPage">
|
||
<div id="SRIndex">
|
||
<div id="SRResults"></div>
|
||
<div class="SRStatus" id="Loading">Loading...</div>
|
||
<div class="SRStatus" id="Searching">Searching...</div>
|
||
<div class="SRStatus" id="NoMatches">No Matches</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div><div class="header">
|
||
<div class="headertitle"><div class="title">Freeing Memory Allocated by the HDF5 Library </div></div>
|
||
</div><!--header-->
|
||
<div class="contents">
|
||
<div class="textblock"><p>Navigate back: <a class="el" href="index.html" title="notitle">Main</a> / <a class="el" href="_u_g.html" title="HDF5 User Guide">HDF5 User Guide</a> / <a class="el" href="_a_r__u_g.html" title="Additional Resources">Additional Resources</a> </p><hr />
|
||
<p>Several functions in the HDF5 C API return buffers allocated by the HDF5 Library. When application code uses a different library for memory management than the HDF Library, a corrupt heap or a resource leak can occur when these allocated buffers are freed. This is most commonly a problem on Windows systems since Microsoft implements C library functions in Visual Studio-specific libraries which do not share heap state.</p>
|
||
<p>Introduced with HDF5 Release 1.8.13 May 15, 2014</p>
|
||
<p>This document describes this problem and the steps users can take to mitigate the problem. This document also introduces the new <a class="el" href="group___h5.html#ga71872bf6445cba956da86d4762b662cf" title="Frees memory allocated by the HDF5 library.">H5free_memory</a> function.</p>
|
||
<h1 class="doxsection"><a class="anchor" id="sec_freeing_memory_intro"></a>
|
||
Introduction</h1>
|
||
<p>In the HDF5 Library, responsibility for the allocation and freeing of memory is usually the responsibility of the same component: either the library or the user's code. When data that would normally be stored in dynamicallyallocated memory must be returned from the library, the user is usually asked to allocate a buffer which is passed to the function and then filled by the library. The complication is that the user must be able to determine the buffer's size. The mechanism for this is for the user to make a preliminary call, passing a NULL pointer in for the buffer. The function will then return the appropriate number of bytes for the user to allocate. See the example below.</p>
|
||
<p><em>Example1. Determining the buffer size with a preliminary call</em> </p><div class="fragment"><div class="line">ssize_t size;</div>
|
||
<div class="line"><span class="keywordtype">size_t</span> bufsize;</div>
|
||
<div class="line"><a class="code hl_typedef" href="_h5_ipublic_8h.html#a0045db7ff9c22ad35db6ae91662e1943">hid_t</a> object_id;</div>
|
||
<div class="line"><span class="keywordtype">char</span> *comment;</div>
|
||
<div class="line">…</div>
|
||
<div class="line">size = <a class="code hl_function" href="group___h5_o.html#gaa1511ce5e2fe01ce7ea58f2f851d694b">H5Oget_comment</a>(object_id, NULL, bufsize); <span class="comment">// determine size</span></div>
|
||
<div class="line">bufsize = size;</div>
|
||
<div class="line">comment = (<span class="keywordtype">char</span> *)malloc(bufsize * <span class="keyword">sizeof</span>(<span class="keywordtype">char</span>));</div>
|
||
<div class="line">size = <a class="code hl_function" href="group___h5_o.html#gaa1511ce5e2fe01ce7ea58f2f851d694b">H5Oget_comment</a>(object_id, comment, bufsize); <span class="comment">// fill buffer</span></div>
|
||
<div class="ttc" id="a_h5_ipublic_8h_html_a0045db7ff9c22ad35db6ae91662e1943"><div class="ttname"><a href="_h5_ipublic_8h.html#a0045db7ff9c22ad35db6ae91662e1943">hid_t</a></div><div class="ttdeci">int64_t hid_t</div><div class="ttdef"><b>Definition</b> H5Ipublic.h:60</div></div>
|
||
<div class="ttc" id="agroup___h5_o_html_gaa1511ce5e2fe01ce7ea58f2f851d694b"><div class="ttname"><a href="group___h5_o.html#gaa1511ce5e2fe01ce7ea58f2f851d694b">H5Oget_comment</a></div><div class="ttdeci">ssize_t H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize)</div><div class="ttdoc">Retrieves comment for specified object.</div></div>
|
||
</div><!-- fragment --><p>There are, however, several API calls in which the buffer is allocated by the HDF5 Library and returned to the user who is responsible for freeing it. This can be a problem when memory in the application and HDF5 Library are managed via different libraries as it can result in resource leaks or a corrupted heap. This heap corruption can result in subtle bugs that can be very difficult to reproduce and diagnose. In most cases, having the library allocate memory and the application free it is not a problem since memory operations will resolve down to the operating system's memory manager; however, there are cases where this is not true. For example, a debug memory manager may be in use by the application code but not the library. A complication that is unique to Windows is that the C standard library functions are implemented in VisualStudiospecific C run-time (CRT) libraries. When different versions of Visual Studio are used to compile the library and application code, the allocate and free calls are made in different libraries, which do not share state, leading to the previously mentioned resource and corruption issues.</p>
|
||
<h1 class="doxsection"><a class="anchor" id="sec_freeing_memory_crt"></a>
|
||
The Windows C Run-time (CRT)</h1>
|
||
<p>Microsoft implements the standard C library functions in debug and release libraries that are specific to each version of Visual Studio<sup>1</sup>. Each library is a separate entity and maintains its own internal CRT object state, file handles, and heap information. Creating an object in one CRT and destroying it in another CRT may appear to work but can cause corruption of one CRT and resource leaks in the other.</p>
|
||
<table class="doxtable">
|
||
<tr>
|
||
<td><div class="image">
|
||
<img src="FreeingMemory_fig1.png" alt=""/>
|
||
</div>
|
||
</td></tr>
|
||
</table>
|
||
<p>These problems are normally avoided on Windows by ensuring that all components that can return CRT resources are linked to the same CRT dynamic link library (DLL). Unfortunately, even debug and release CRTs are housed in separate DLLs, so this is not an easy solution to implement. Using static linkage does not avoid this problem since separate copies of the CRT are created in each statically linked component.</p>
|
||
<ul>
|
||
<li><sup>1</sup> The names of these libraries are of the form MSVCR<#>.dll, where <#> is the Visual Studio version. For example, MSVCR110.dll corresponds to Visual Studio 11.0 (2012).</li>
|
||
</ul>
|
||
<h1 class="doxsection"><a class="anchor" id="sec_freeing_memory_api"></a>
|
||
Affected API Calls</h1>
|
||
<p>This is a list of the API calls that are affected. </p><ul>
|
||
<li><a class="el" href="group___h5_e.html#ga91fa7fb56da6f08f9c293a6ce89c7819" title="Returns a character string describing an error specified by a major error number.">H5Eget_major</a> </li>
|
||
<li><a class="el" href="group___h5_e.html#ga4975325db13bc5cf44d72d4ef0394034" title="Returns a character string describing an error specified by a minor error number.">H5Eget_minor</a> </li>
|
||
<li><a class="el" href="group___p_l_c_r_a.html#gac94a17bcb6d988a7ccb1cf2c6f4a3a82" title="Retrieves the name of a class.">H5Pget_class_name</a> </li>
|
||
<li><a class="el" href="group___c_o_m_p_e_n_u_m.html#ga64d1d807464d2011192f28115580fb66" title="Retrieves the name of a compound or enumeration datatype member.">H5Tget_member_name</a> </li>
|
||
<li><a class="el" href="group___o_p_a_q_u_e.html#gaf1d0f634ac1a3b4220b8fe0197b93832" title="Gets the tag associated with an opaque datatype.">H5Tget_tag</a></li>
|
||
</ul>
|
||
<h1 class="doxsection"><a class="anchor" id="sec_freeing_memory_mitigation"></a>
|
||
Mitigation</h1>
|
||
<p>There are several potential solutions to the problem of freeing memory allocated by the HDF5 Library.</p>
|
||
<h2 class="doxsection"><a class="anchor" id="subsec_freeing_memory_mitigation1"></a>
|
||
Use the Same Memory Manager/Correct C Run‐time Everywhere</h2>
|
||
<p>Both application code and the HDF5 Library must use the same memory allocator. When using Visual Studio, both the Visual Studio version and release/debug state must be identical. As of HDF5 1.8.12, this is the only available solution.</p>
|
||
<h2 class="doxsection"><a class="anchor" id="subsec_freeing_memory_mitigation2"></a>
|
||
Use the H5free_memory Function</h2>
|
||
<p>A new function called <a class="el" href="group___h5.html#ga71872bf6445cba956da86d4762b662cf" title="Frees memory allocated by the HDF5 library.">H5free_memory</a> has been created and is essentially a thin wrapper for the run time's free() call. This function would be used to free any memory allocated by the library. This solution has the advantages of being extremely easy to implement and intuitive to use. It can also be used as a solution with legacy API calls, so it would be necessary even if we modify the HDF5 API. This function will also be extremely useful when HDF5 is wrapped for use with managed languages such as Java, .NET, and Python so that the wrappers can properly clean up resources.</p>
|
||
<p>See the <a class="el" href="group___h5.html#ga71872bf6445cba956da86d4762b662cf" title="Frees memory allocated by the HDF5 library.">H5free_memory</a> entry in the <a class="el" href="_r_m.html" title="HDF5 Reference Manual">HDF5 Reference Manual</a> for more information.</p>
|
||
<p>Note that the creation of this function does not imply that it will be acceptable for new API calls to be created that return libraryallocated memory. The preferred mechanism will still be to use the "preliminary call" scheme described in the "Introduction" on page 4 where the user allocates the buffer.</p>
|
||
<hr />
|
||
<p> Navigate back: <a class="el" href="index.html" title="notitle">Main</a> / <a class="el" href="_u_g.html" title="HDF5 User Guide">HDF5 User Guide</a> / <a class="el" href="_a_r__u_g.html" title="Additional Resources">Additional Resources</a> </p>
|
||
</div></div><!-- contents -->
|
||
</div><!-- PageDoc -->
|
||
</div><!-- doc-content -->
|
||
<div id="page-nav" class="page-nav-panel">
|
||
<div id="page-nav-resize-handle"></div>
|
||
<div id="page-nav-tree">
|
||
<div id="page-nav-contents">
|
||
</div><!-- page-nav-contents -->
|
||
</div><!-- page-nav-tree -->
|
||
</div><!-- page-nav -->
|
||
</div><!-- container -->
|
||
<!-- start footer part -->
|
||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||
<ul>
|
||
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.16.1 </li>
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|