814 lines
64 KiB
HTML
814 lines
64 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>Memory Management — Python 3.7.4 documentation</title>
|
||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
|
||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||
|
||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="Search within Python 3.7.4 documentation"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="About these documents" href="../about.html" />
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||
<link rel="next" title="Object Implementation Support" href="objimpl.html" />
|
||
<link rel="prev" title="Initialization, Finalization, and Threads" href="init.html" />
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||
<link rel="canonical" href="https://docs.python.org/3/c-api/memory.html" />
|
||
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
|
||
</head><body>
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="objimpl.html" title="Object Implementation Support"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="init.html" title="Initialization, Finalization, and Threads"
|
||
accesskey="P">previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python/C API Reference Manual</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<div class="section" id="memory-management">
|
||
<span id="memory"></span><h1>Memory Management<a class="headerlink" href="#memory-management" title="Permalink to this headline">¶</a></h1>
|
||
<div class="section" id="overview">
|
||
<span id="memoryoverview"></span><h2>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
|
||
<p>Memory management in Python involves a private heap containing all Python
|
||
objects and data structures. The management of this private heap is ensured
|
||
internally by the <em>Python memory manager</em>. The Python memory manager has
|
||
different components which deal with various dynamic storage management aspects,
|
||
like sharing, segmentation, preallocation or caching.</p>
|
||
<p>At the lowest level, a raw memory allocator ensures that there is enough room in
|
||
the private heap for storing all Python-related data by interacting with the
|
||
memory manager of the operating system. On top of the raw memory allocator,
|
||
several object-specific allocators operate on the same heap and implement
|
||
distinct memory management policies adapted to the peculiarities of every object
|
||
type. For example, integer objects are managed differently within the heap than
|
||
strings, tuples or dictionaries because integers imply different storage
|
||
requirements and speed/space tradeoffs. The Python memory manager thus delegates
|
||
some of the work to the object-specific allocators, but ensures that the latter
|
||
operate within the bounds of the private heap.</p>
|
||
<p>It is important to understand that the management of the Python heap is
|
||
performed by the interpreter itself and that the user has no control over it,
|
||
even if they regularly manipulate object pointers to memory blocks inside that
|
||
heap. The allocation of heap space for Python objects and other internal
|
||
buffers is performed on demand by the Python memory manager through the Python/C
|
||
API functions listed in this document.</p>
|
||
<p id="index-0">To avoid memory corruption, extension writers should never try to operate on
|
||
Python objects with the functions exported by the C library: <code class="xref c c-func docutils literal notranslate"><span class="pre">malloc()</span></code>,
|
||
<code class="xref c c-func docutils literal notranslate"><span class="pre">calloc()</span></code>, <code class="xref c c-func docutils literal notranslate"><span class="pre">realloc()</span></code> and <code class="xref c c-func docutils literal notranslate"><span class="pre">free()</span></code>. This will result in mixed
|
||
calls between the C allocator and the Python memory manager with fatal
|
||
consequences, because they implement different algorithms and operate on
|
||
different heaps. However, one may safely allocate and release memory blocks
|
||
with the C library allocator for individual purposes, as shown in the following
|
||
example:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span> <span class="o">*</span><span class="n">res</span><span class="p">;</span>
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">buf</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span> <span class="n">malloc</span><span class="p">(</span><span class="n">BUFSIZ</span><span class="p">);</span> <span class="cm">/* for I/O */</span>
|
||
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">buf</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">PyErr_NoMemory</span><span class="p">();</span>
|
||
<span class="p">...</span><span class="n">Do</span> <span class="n">some</span> <span class="n">I</span><span class="o">/</span><span class="n">O</span> <span class="n">operation</span> <span class="n">involving</span> <span class="n">buf</span><span class="p">...</span>
|
||
<span class="n">res</span> <span class="o">=</span> <span class="n">PyBytes_FromString</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
|
||
<span class="n">free</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span> <span class="cm">/* malloc'ed */</span>
|
||
<span class="k">return</span> <span class="n">res</span><span class="p">;</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>In this example, the memory request for the I/O buffer is handled by the C
|
||
library allocator. The Python memory manager is involved only in the allocation
|
||
of the bytes object returned as a result.</p>
|
||
<p>In most situations, however, it is recommended to allocate memory from the
|
||
Python heap specifically because the latter is under control of the Python
|
||
memory manager. For example, this is required when the interpreter is extended
|
||
with new object types written in C. Another reason for using the Python heap is
|
||
the desire to <em>inform</em> the Python memory manager about the memory needs of the
|
||
extension module. Even when the requested memory is used exclusively for
|
||
internal, highly-specific purposes, delegating all memory requests to the Python
|
||
memory manager causes the interpreter to have a more accurate image of its
|
||
memory footprint as a whole. Consequently, under certain circumstances, the
|
||
Python memory manager may or may not trigger appropriate actions, like garbage
|
||
collection, memory compaction or other preventive procedures. Note that by using
|
||
the C library allocator as shown in the previous example, the allocated memory
|
||
for the I/O buffer escapes completely the Python memory manager.</p>
|
||
<div class="admonition seealso">
|
||
<p class="admonition-title">See also</p>
|
||
<p>The <span class="target" id="index-1"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONMALLOC"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONMALLOC</span></code></a> environment variable can be used to configure
|
||
the memory allocators used by Python.</p>
|
||
<p>The <span class="target" id="index-2"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONMALLOCSTATS"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONMALLOCSTATS</span></code></a> environment variable can be used to print
|
||
statistics of the <a class="reference internal" href="#pymalloc"><span class="std std-ref">pymalloc memory allocator</span></a> every time a
|
||
new pymalloc object arena is created, and on shutdown.</p>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="raw-memory-interface">
|
||
<h2>Raw Memory Interface<a class="headerlink" href="#raw-memory-interface" title="Permalink to this headline">¶</a></h2>
|
||
<p>The following function sets are wrappers to the system allocator. These
|
||
functions are thread-safe, the <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">GIL</span></a> does not
|
||
need to be held.</p>
|
||
<p>The <a class="reference internal" href="#default-memory-allocators"><span class="std std-ref">default raw memory allocator</span></a> uses
|
||
the following functions: <code class="xref c c-func docutils literal notranslate"><span class="pre">malloc()</span></code>, <code class="xref c c-func docutils literal notranslate"><span class="pre">calloc()</span></code>, <code class="xref c c-func docutils literal notranslate"><span class="pre">realloc()</span></code>
|
||
and <code class="xref c c-func docutils literal notranslate"><span class="pre">free()</span></code>; call <code class="docutils literal notranslate"><span class="pre">malloc(1)</span></code> (or <code class="docutils literal notranslate"><span class="pre">calloc(1,</span> <span class="pre">1)</span></code>) when requesting
|
||
zero bytes.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.4.</span></p>
|
||
</div>
|
||
<dl class="function">
|
||
<dt id="c.PyMem_RawMalloc">
|
||
void* <code class="descname">PyMem_RawMalloc</code><span class="sig-paren">(</span>size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_RawMalloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Allocates <em>n</em> bytes and returns a pointer of type <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> to the
|
||
allocated memory, or <em>NULL</em> if the request fails.</p>
|
||
<p>Requesting zero bytes returns a distinct non-<em>NULL</em> pointer if possible, as
|
||
if <code class="docutils literal notranslate"><span class="pre">PyMem_RawMalloc(1)</span></code> had been called instead. The memory will not have
|
||
been initialized in any way.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_RawCalloc">
|
||
void* <code class="descname">PyMem_RawCalloc</code><span class="sig-paren">(</span>size_t<em> nelem</em>, size_t<em> elsize</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_RawCalloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Allocates <em>nelem</em> elements each whose size in bytes is <em>elsize</em> and returns
|
||
a pointer of type <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> to the allocated memory, or <em>NULL</em> if the
|
||
request fails. The memory is initialized to zeros.</p>
|
||
<p>Requesting zero elements or elements of size zero bytes returns a distinct
|
||
non-<em>NULL</em> pointer if possible, as if <code class="docutils literal notranslate"><span class="pre">PyMem_RawCalloc(1,</span> <span class="pre">1)</span></code> had been
|
||
called instead.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.5.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_RawRealloc">
|
||
void* <code class="descname">PyMem_RawRealloc</code><span class="sig-paren">(</span>void<em> *p</em>, size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_RawRealloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Resizes the memory block pointed to by <em>p</em> to <em>n</em> bytes. The contents will
|
||
be unchanged to the minimum of the old and the new sizes.</p>
|
||
<p>If <em>p</em> is <em>NULL</em>, the call is equivalent to <code class="docutils literal notranslate"><span class="pre">PyMem_RawMalloc(n)</span></code>; else if
|
||
<em>n</em> is equal to zero, the memory block is resized but is not freed, and the
|
||
returned pointer is non-<em>NULL</em>.</p>
|
||
<p>Unless <em>p</em> is <em>NULL</em>, it must have been returned by a previous call to
|
||
<a class="reference internal" href="#c.PyMem_RawMalloc" title="PyMem_RawMalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawMalloc()</span></code></a>, <a class="reference internal" href="#c.PyMem_RawRealloc" title="PyMem_RawRealloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawRealloc()</span></code></a> or
|
||
<a class="reference internal" href="#c.PyMem_RawCalloc" title="PyMem_RawCalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawCalloc()</span></code></a>.</p>
|
||
<p>If the request fails, <a class="reference internal" href="#c.PyMem_RawRealloc" title="PyMem_RawRealloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawRealloc()</span></code></a> returns <em>NULL</em> and <em>p</em>
|
||
remains a valid pointer to the previous memory area.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_RawFree">
|
||
void <code class="descname">PyMem_RawFree</code><span class="sig-paren">(</span>void<em> *p</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_RawFree" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Frees the memory block pointed to by <em>p</em>, which must have been returned by a
|
||
previous call to <a class="reference internal" href="#c.PyMem_RawMalloc" title="PyMem_RawMalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawMalloc()</span></code></a>, <a class="reference internal" href="#c.PyMem_RawRealloc" title="PyMem_RawRealloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawRealloc()</span></code></a> or
|
||
<a class="reference internal" href="#c.PyMem_RawCalloc" title="PyMem_RawCalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawCalloc()</span></code></a>. Otherwise, or if <code class="docutils literal notranslate"><span class="pre">PyMem_RawFree(p)</span></code> has been
|
||
called before, undefined behavior occurs.</p>
|
||
<p>If <em>p</em> is <em>NULL</em>, no operation is performed.</p>
|
||
</dd></dl>
|
||
|
||
</div>
|
||
<div class="section" id="memory-interface">
|
||
<span id="memoryinterface"></span><h2>Memory Interface<a class="headerlink" href="#memory-interface" title="Permalink to this headline">¶</a></h2>
|
||
<p>The following function sets, modeled after the ANSI C standard, but specifying
|
||
behavior when requesting zero bytes, are available for allocating and releasing
|
||
memory from the Python heap.</p>
|
||
<p>The <a class="reference internal" href="#default-memory-allocators"><span class="std std-ref">default memory allocator</span></a> uses the
|
||
<a class="reference internal" href="#pymalloc"><span class="std std-ref">pymalloc memory allocator</span></a>.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>The <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">GIL</span></a> must be held when using these
|
||
functions.</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.6: </span>The default allocator is now pymalloc instead of system <code class="xref c c-func docutils literal notranslate"><span class="pre">malloc()</span></code>.</p>
|
||
</div>
|
||
<dl class="function">
|
||
<dt id="c.PyMem_Malloc">
|
||
void* <code class="descname">PyMem_Malloc</code><span class="sig-paren">(</span>size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_Malloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Allocates <em>n</em> bytes and returns a pointer of type <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> to the
|
||
allocated memory, or <em>NULL</em> if the request fails.</p>
|
||
<p>Requesting zero bytes returns a distinct non-<em>NULL</em> pointer if possible, as
|
||
if <code class="docutils literal notranslate"><span class="pre">PyMem_Malloc(1)</span></code> had been called instead. The memory will not have
|
||
been initialized in any way.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_Calloc">
|
||
void* <code class="descname">PyMem_Calloc</code><span class="sig-paren">(</span>size_t<em> nelem</em>, size_t<em> elsize</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_Calloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Allocates <em>nelem</em> elements each whose size in bytes is <em>elsize</em> and returns
|
||
a pointer of type <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> to the allocated memory, or <em>NULL</em> if the
|
||
request fails. The memory is initialized to zeros.</p>
|
||
<p>Requesting zero elements or elements of size zero bytes returns a distinct
|
||
non-<em>NULL</em> pointer if possible, as if <code class="docutils literal notranslate"><span class="pre">PyMem_Calloc(1,</span> <span class="pre">1)</span></code> had been called
|
||
instead.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.5.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_Realloc">
|
||
void* <code class="descname">PyMem_Realloc</code><span class="sig-paren">(</span>void<em> *p</em>, size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_Realloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Resizes the memory block pointed to by <em>p</em> to <em>n</em> bytes. The contents will be
|
||
unchanged to the minimum of the old and the new sizes.</p>
|
||
<p>If <em>p</em> is <em>NULL</em>, the call is equivalent to <code class="docutils literal notranslate"><span class="pre">PyMem_Malloc(n)</span></code>; else if <em>n</em>
|
||
is equal to zero, the memory block is resized but is not freed, and the
|
||
returned pointer is non-<em>NULL</em>.</p>
|
||
<p>Unless <em>p</em> is <em>NULL</em>, it must have been returned by a previous call to
|
||
<a class="reference internal" href="#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a>, <a class="reference internal" href="#c.PyMem_Realloc" title="PyMem_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Realloc()</span></code></a> or <a class="reference internal" href="#c.PyMem_Calloc" title="PyMem_Calloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Calloc()</span></code></a>.</p>
|
||
<p>If the request fails, <a class="reference internal" href="#c.PyMem_Realloc" title="PyMem_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Realloc()</span></code></a> returns <em>NULL</em> and <em>p</em> remains
|
||
a valid pointer to the previous memory area.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_Free">
|
||
void <code class="descname">PyMem_Free</code><span class="sig-paren">(</span>void<em> *p</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_Free" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Frees the memory block pointed to by <em>p</em>, which must have been returned by a
|
||
previous call to <a class="reference internal" href="#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a>, <a class="reference internal" href="#c.PyMem_Realloc" title="PyMem_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Realloc()</span></code></a> or
|
||
<a class="reference internal" href="#c.PyMem_Calloc" title="PyMem_Calloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Calloc()</span></code></a>. Otherwise, or if <code class="docutils literal notranslate"><span class="pre">PyMem_Free(p)</span></code> has been called
|
||
before, undefined behavior occurs.</p>
|
||
<p>If <em>p</em> is <em>NULL</em>, no operation is performed.</p>
|
||
</dd></dl>
|
||
|
||
<p>The following type-oriented macros are provided for convenience. Note that
|
||
<em>TYPE</em> refers to any C type.</p>
|
||
<dl class="function">
|
||
<dt id="c.PyMem_New">
|
||
TYPE* <code class="descname">PyMem_New</code><span class="sig-paren">(</span>TYPE, size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_New" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Same as <a class="reference internal" href="#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a>, but allocates <code class="docutils literal notranslate"><span class="pre">(n</span> <span class="pre">*</span> <span class="pre">sizeof(TYPE))</span></code> bytes of
|
||
memory. Returns a pointer cast to <code class="xref c c-type docutils literal notranslate"><span class="pre">TYPE*</span></code>. The memory will not have
|
||
been initialized in any way.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_Resize">
|
||
TYPE* <code class="descname">PyMem_Resize</code><span class="sig-paren">(</span>void<em> *p</em>, TYPE, size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_Resize" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Same as <a class="reference internal" href="#c.PyMem_Realloc" title="PyMem_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Realloc()</span></code></a>, but the memory block is resized to <code class="docutils literal notranslate"><span class="pre">(n</span> <span class="pre">*</span>
|
||
<span class="pre">sizeof(TYPE))</span></code> bytes. Returns a pointer cast to <code class="xref c c-type docutils literal notranslate"><span class="pre">TYPE*</span></code>. On return,
|
||
<em>p</em> will be a pointer to the new memory area, or <em>NULL</em> in the event of
|
||
failure.</p>
|
||
<p>This is a C preprocessor macro; <em>p</em> is always reassigned. Save the original
|
||
value of <em>p</em> to avoid losing memory when handling errors.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_Del">
|
||
void <code class="descname">PyMem_Del</code><span class="sig-paren">(</span>void<em> *p</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_Del" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Same as <a class="reference internal" href="#c.PyMem_Free" title="PyMem_Free"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Free()</span></code></a>.</p>
|
||
</dd></dl>
|
||
|
||
<p>In addition, the following macro sets are provided for calling the Python memory
|
||
allocator directly, without involving the C API functions listed above. However,
|
||
note that their use does not preserve binary compatibility across Python
|
||
versions and is therefore deprecated in extension modules.</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">PyMem_MALLOC(size)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">PyMem_NEW(type,</span> <span class="pre">size)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">PyMem_REALLOC(ptr,</span> <span class="pre">size)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">PyMem_RESIZE(ptr,</span> <span class="pre">type,</span> <span class="pre">size)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">PyMem_FREE(ptr)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">PyMem_DEL(ptr)</span></code></p></li>
|
||
</ul>
|
||
</div>
|
||
<div class="section" id="object-allocators">
|
||
<h2>Object allocators<a class="headerlink" href="#object-allocators" title="Permalink to this headline">¶</a></h2>
|
||
<p>The following function sets, modeled after the ANSI C standard, but specifying
|
||
behavior when requesting zero bytes, are available for allocating and releasing
|
||
memory from the Python heap.</p>
|
||
<p>The <a class="reference internal" href="#default-memory-allocators"><span class="std std-ref">default object allocator</span></a> uses the
|
||
<a class="reference internal" href="#pymalloc"><span class="std std-ref">pymalloc memory allocator</span></a>.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>The <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">GIL</span></a> must be held when using these
|
||
functions.</p>
|
||
</div>
|
||
<dl class="function">
|
||
<dt id="c.PyObject_Malloc">
|
||
void* <code class="descname">PyObject_Malloc</code><span class="sig-paren">(</span>size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_Malloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Allocates <em>n</em> bytes and returns a pointer of type <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> to the
|
||
allocated memory, or <em>NULL</em> if the request fails.</p>
|
||
<p>Requesting zero bytes returns a distinct non-<em>NULL</em> pointer if possible, as
|
||
if <code class="docutils literal notranslate"><span class="pre">PyObject_Malloc(1)</span></code> had been called instead. The memory will not have
|
||
been initialized in any way.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyObject_Calloc">
|
||
void* <code class="descname">PyObject_Calloc</code><span class="sig-paren">(</span>size_t<em> nelem</em>, size_t<em> elsize</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_Calloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Allocates <em>nelem</em> elements each whose size in bytes is <em>elsize</em> and returns
|
||
a pointer of type <code class="xref c c-type docutils literal notranslate"><span class="pre">void*</span></code> to the allocated memory, or <em>NULL</em> if the
|
||
request fails. The memory is initialized to zeros.</p>
|
||
<p>Requesting zero elements or elements of size zero bytes returns a distinct
|
||
non-<em>NULL</em> pointer if possible, as if <code class="docutils literal notranslate"><span class="pre">PyObject_Calloc(1,</span> <span class="pre">1)</span></code> had been called
|
||
instead.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.5.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyObject_Realloc">
|
||
void* <code class="descname">PyObject_Realloc</code><span class="sig-paren">(</span>void<em> *p</em>, size_t<em> n</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_Realloc" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Resizes the memory block pointed to by <em>p</em> to <em>n</em> bytes. The contents will be
|
||
unchanged to the minimum of the old and the new sizes.</p>
|
||
<p>If <em>p</em> is <em>NULL</em>, the call is equivalent to <code class="docutils literal notranslate"><span class="pre">PyObject_Malloc(n)</span></code>; else if <em>n</em>
|
||
is equal to zero, the memory block is resized but is not freed, and the
|
||
returned pointer is non-<em>NULL</em>.</p>
|
||
<p>Unless <em>p</em> is <em>NULL</em>, it must have been returned by a previous call to
|
||
<a class="reference internal" href="#c.PyObject_Malloc" title="PyObject_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Malloc()</span></code></a>, <a class="reference internal" href="#c.PyObject_Realloc" title="PyObject_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Realloc()</span></code></a> or <a class="reference internal" href="#c.PyObject_Calloc" title="PyObject_Calloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Calloc()</span></code></a>.</p>
|
||
<p>If the request fails, <a class="reference internal" href="#c.PyObject_Realloc" title="PyObject_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Realloc()</span></code></a> returns <em>NULL</em> and <em>p</em> remains
|
||
a valid pointer to the previous memory area.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyObject_Free">
|
||
void <code class="descname">PyObject_Free</code><span class="sig-paren">(</span>void<em> *p</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_Free" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Frees the memory block pointed to by <em>p</em>, which must have been returned by a
|
||
previous call to <a class="reference internal" href="#c.PyObject_Malloc" title="PyObject_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Malloc()</span></code></a>, <a class="reference internal" href="#c.PyObject_Realloc" title="PyObject_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Realloc()</span></code></a> or
|
||
<a class="reference internal" href="#c.PyObject_Calloc" title="PyObject_Calloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Calloc()</span></code></a>. Otherwise, or if <code class="docutils literal notranslate"><span class="pre">PyObject_Free(p)</span></code> has been called
|
||
before, undefined behavior occurs.</p>
|
||
<p>If <em>p</em> is <em>NULL</em>, no operation is performed.</p>
|
||
</dd></dl>
|
||
|
||
</div>
|
||
<div class="section" id="default-memory-allocators">
|
||
<span id="id1"></span><h2>Default Memory Allocators<a class="headerlink" href="#default-memory-allocators" title="Permalink to this headline">¶</a></h2>
|
||
<p>Default memory allocators:</p>
|
||
<table class="docutils align-center">
|
||
<colgroup>
|
||
<col style="width: 28%" />
|
||
<col style="width: 18%" />
|
||
<col style="width: 16%" />
|
||
<col style="width: 19%" />
|
||
<col style="width: 18%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Configuration</p></th>
|
||
<th class="head"><p>Name</p></th>
|
||
<th class="head"><p>PyMem_RawMalloc</p></th>
|
||
<th class="head"><p>PyMem_Malloc</p></th>
|
||
<th class="head"><p>PyObject_Malloc</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p>Release build</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">"pymalloc"</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">pymalloc</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">pymalloc</span></code></p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>Debug build</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">"pymalloc_debug"</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code> + debug</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">pymalloc</span></code> + debug</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">pymalloc</span></code> + debug</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>Release build, without pymalloc</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">"malloc"</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code></p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>Debug build, without pymalloc</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">"malloc_debug"</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code> + debug</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code> + debug</p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code> + debug</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Legend:</p>
|
||
<ul class="simple">
|
||
<li><p>Name: value for <span class="target" id="index-3"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONMALLOC"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONMALLOC</span></code></a> environment variable</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">malloc</span></code>: system allocators from the standard C library, C functions:
|
||
<code class="xref c c-func docutils literal notranslate"><span class="pre">malloc()</span></code>, <code class="xref c c-func docutils literal notranslate"><span class="pre">calloc()</span></code>, <code class="xref c c-func docutils literal notranslate"><span class="pre">realloc()</span></code> and <code class="xref c c-func docutils literal notranslate"><span class="pre">free()</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">pymalloc</span></code>: <a class="reference internal" href="#pymalloc"><span class="std std-ref">pymalloc memory allocator</span></a></p></li>
|
||
<li><p>“+ debug”: with debug hooks installed by <a class="reference internal" href="#c.PyMem_SetupDebugHooks" title="PyMem_SetupDebugHooks"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_SetupDebugHooks()</span></code></a></p></li>
|
||
</ul>
|
||
</div>
|
||
<div class="section" id="customize-memory-allocators">
|
||
<h2>Customize Memory Allocators<a class="headerlink" href="#customize-memory-allocators" title="Permalink to this headline">¶</a></h2>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.4.</span></p>
|
||
</div>
|
||
<dl class="type">
|
||
<dt id="c.PyMemAllocatorEx">
|
||
<code class="descname">PyMemAllocatorEx</code><a class="headerlink" href="#c.PyMemAllocatorEx" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Structure used to describe a memory block allocator. The structure has
|
||
four fields:</p>
|
||
<table class="docutils align-center">
|
||
<colgroup>
|
||
<col style="width: 60%" />
|
||
<col style="width: 40%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Field</p></th>
|
||
<th class="head"><p>Meaning</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*ctx</span></code></p></td>
|
||
<td><p>user context passed as first argument</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">void*</span> <span class="pre">malloc(void</span> <span class="pre">*ctx,</span> <span class="pre">size_t</span> <span class="pre">size)</span></code></p></td>
|
||
<td><p>allocate a memory block</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">void*</span> <span class="pre">calloc(void</span> <span class="pre">*ctx,</span> <span class="pre">size_t</span> <span class="pre">nelem,</span> <span class="pre">size_t</span> <span class="pre">elsize)</span></code></p></td>
|
||
<td><p>allocate a memory block initialized
|
||
with zeros</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">void*</span> <span class="pre">realloc(void</span> <span class="pre">*ctx,</span> <span class="pre">void</span> <span class="pre">*ptr,</span> <span class="pre">size_t</span> <span class="pre">new_size)</span></code></p></td>
|
||
<td><p>allocate or resize a memory block</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">free(void</span> <span class="pre">*ctx,</span> <span class="pre">void</span> <span class="pre">*ptr)</span></code></p></td>
|
||
<td><p>free a memory block</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.5: </span>The <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMemAllocator</span></code> structure was renamed to
|
||
<a class="reference internal" href="#c.PyMemAllocatorEx" title="PyMemAllocatorEx"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMemAllocatorEx</span></code></a> and a new <code class="docutils literal notranslate"><span class="pre">calloc</span></code> field was added.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="type">
|
||
<dt id="c.PyMemAllocatorDomain">
|
||
<code class="descname">PyMemAllocatorDomain</code><a class="headerlink" href="#c.PyMemAllocatorDomain" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Enum used to identify an allocator domain. Domains:</p>
|
||
<dl class="var">
|
||
<dt id="c.PYMEM_DOMAIN_RAW">
|
||
<code class="descname">PYMEM_DOMAIN_RAW</code><a class="headerlink" href="#c.PYMEM_DOMAIN_RAW" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Functions:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference internal" href="#c.PyMem_RawMalloc" title="PyMem_RawMalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawMalloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyMem_RawRealloc" title="PyMem_RawRealloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawRealloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyMem_RawCalloc" title="PyMem_RawCalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawCalloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyMem_RawFree" title="PyMem_RawFree"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawFree()</span></code></a></p></li>
|
||
</ul>
|
||
</dd></dl>
|
||
|
||
<dl class="var">
|
||
<dt id="c.PYMEM_DOMAIN_MEM">
|
||
<code class="descname">PYMEM_DOMAIN_MEM</code><a class="headerlink" href="#c.PYMEM_DOMAIN_MEM" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Functions:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference internal" href="#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a>,</p></li>
|
||
<li><p><a class="reference internal" href="#c.PyMem_Realloc" title="PyMem_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Realloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyMem_Calloc" title="PyMem_Calloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Calloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyMem_Free" title="PyMem_Free"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Free()</span></code></a></p></li>
|
||
</ul>
|
||
</dd></dl>
|
||
|
||
<dl class="var">
|
||
<dt id="c.PYMEM_DOMAIN_OBJ">
|
||
<code class="descname">PYMEM_DOMAIN_OBJ</code><a class="headerlink" href="#c.PYMEM_DOMAIN_OBJ" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Functions:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference internal" href="#c.PyObject_Malloc" title="PyObject_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Malloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyObject_Realloc" title="PyObject_Realloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Realloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyObject_Calloc" title="PyObject_Calloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Calloc()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#c.PyObject_Free" title="PyObject_Free"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Free()</span></code></a></p></li>
|
||
</ul>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_GetAllocator">
|
||
void <code class="descname">PyMem_GetAllocator</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyMemAllocatorDomain" title="PyMemAllocatorDomain">PyMemAllocatorDomain</a><em> domain</em>, <a class="reference internal" href="#c.PyMemAllocatorEx" title="PyMemAllocatorEx">PyMemAllocatorEx</a><em> *allocator</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_GetAllocator" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Get the memory block allocator of the specified domain.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_SetAllocator">
|
||
void <code class="descname">PyMem_SetAllocator</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyMemAllocatorDomain" title="PyMemAllocatorDomain">PyMemAllocatorDomain</a><em> domain</em>, <a class="reference internal" href="#c.PyMemAllocatorEx" title="PyMemAllocatorEx">PyMemAllocatorEx</a><em> *allocator</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_SetAllocator" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Set the memory block allocator of the specified domain.</p>
|
||
<p>The new allocator must return a distinct non-NULL pointer when requesting
|
||
zero bytes.</p>
|
||
<p>For the <a class="reference internal" href="#c.PYMEM_DOMAIN_RAW" title="PYMEM_DOMAIN_RAW"><code class="xref c c-data docutils literal notranslate"><span class="pre">PYMEM_DOMAIN_RAW</span></code></a> domain, the allocator must be
|
||
thread-safe: the <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">GIL</span></a> is not held when the
|
||
allocator is called.</p>
|
||
<p>If the new allocator is not a hook (does not call the previous allocator),
|
||
the <a class="reference internal" href="#c.PyMem_SetupDebugHooks" title="PyMem_SetupDebugHooks"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_SetupDebugHooks()</span></code></a> function must be called to reinstall the
|
||
debug hooks on top on the new allocator.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyMem_SetupDebugHooks">
|
||
void <code class="descname">PyMem_SetupDebugHooks</code><span class="sig-paren">(</span>void<span class="sig-paren">)</span><a class="headerlink" href="#c.PyMem_SetupDebugHooks" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Setup hooks to detect bugs in the Python memory allocator functions.</p>
|
||
<p>Newly allocated memory is filled with the byte <code class="docutils literal notranslate"><span class="pre">0xCD</span></code> (<code class="docutils literal notranslate"><span class="pre">CLEANBYTE</span></code>),
|
||
freed memory is filled with the byte <code class="docutils literal notranslate"><span class="pre">0xDD</span></code> (<code class="docutils literal notranslate"><span class="pre">DEADBYTE</span></code>). Memory blocks
|
||
are surrounded by “forbidden bytes” (<code class="docutils literal notranslate"><span class="pre">FORBIDDENBYTE</span></code>: byte <code class="docutils literal notranslate"><span class="pre">0xFD</span></code>).</p>
|
||
<p>Runtime checks:</p>
|
||
<ul class="simple">
|
||
<li><p>Detect API violations, ex: <a class="reference internal" href="#c.PyObject_Free" title="PyObject_Free"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Free()</span></code></a> called on a buffer
|
||
allocated by <a class="reference internal" href="#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a></p></li>
|
||
<li><p>Detect write before the start of the buffer (buffer underflow)</p></li>
|
||
<li><p>Detect write after the end of the buffer (buffer overflow)</p></li>
|
||
<li><p>Check that the <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">GIL</span></a> is held when
|
||
allocator functions of <a class="reference internal" href="#c.PYMEM_DOMAIN_OBJ" title="PYMEM_DOMAIN_OBJ"><code class="xref c c-data docutils literal notranslate"><span class="pre">PYMEM_DOMAIN_OBJ</span></code></a> (ex:
|
||
<a class="reference internal" href="#c.PyObject_Malloc" title="PyObject_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Malloc()</span></code></a>) and <a class="reference internal" href="#c.PYMEM_DOMAIN_MEM" title="PYMEM_DOMAIN_MEM"><code class="xref c c-data docutils literal notranslate"><span class="pre">PYMEM_DOMAIN_MEM</span></code></a> (ex:
|
||
<a class="reference internal" href="#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a>) domains are called</p></li>
|
||
</ul>
|
||
<p>On error, the debug hooks use the <a class="reference internal" href="../library/tracemalloc.html#module-tracemalloc" title="tracemalloc: Trace memory allocations."><code class="xref py py-mod docutils literal notranslate"><span class="pre">tracemalloc</span></code></a> module to get the
|
||
traceback where a memory block was allocated. The traceback is only
|
||
displayed if <a class="reference internal" href="../library/tracemalloc.html#module-tracemalloc" title="tracemalloc: Trace memory allocations."><code class="xref py py-mod docutils literal notranslate"><span class="pre">tracemalloc</span></code></a> is tracing Python memory allocations and the
|
||
memory block was traced.</p>
|
||
<p>These hooks are <a class="reference internal" href="#default-memory-allocators"><span class="std std-ref">installed by default</span></a> if
|
||
Python is compiled in debug
|
||
mode. The <span class="target" id="index-4"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONMALLOC"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONMALLOC</span></code></a> environment variable can be used to install
|
||
debug hooks on a Python compiled in release mode.</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.6: </span>This function now also works on Python compiled in release mode.
|
||
On error, the debug hooks now use <a class="reference internal" href="../library/tracemalloc.html#module-tracemalloc" title="tracemalloc: Trace memory allocations."><code class="xref py py-mod docutils literal notranslate"><span class="pre">tracemalloc</span></code></a> to get the traceback
|
||
where a memory block was allocated. The debug hooks now also check
|
||
if the GIL is held when functions of <a class="reference internal" href="#c.PYMEM_DOMAIN_OBJ" title="PYMEM_DOMAIN_OBJ"><code class="xref c c-data docutils literal notranslate"><span class="pre">PYMEM_DOMAIN_OBJ</span></code></a> and
|
||
<a class="reference internal" href="#c.PYMEM_DOMAIN_MEM" title="PYMEM_DOMAIN_MEM"><code class="xref c c-data docutils literal notranslate"><span class="pre">PYMEM_DOMAIN_MEM</span></code></a> domains are called.</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.7.3: </span>Byte patterns <code class="docutils literal notranslate"><span class="pre">0xCB</span></code> (<code class="docutils literal notranslate"><span class="pre">CLEANBYTE</span></code>), <code class="docutils literal notranslate"><span class="pre">0xDB</span></code> (<code class="docutils literal notranslate"><span class="pre">DEADBYTE</span></code>) and
|
||
<code class="docutils literal notranslate"><span class="pre">0xFB</span></code> (<code class="docutils literal notranslate"><span class="pre">FORBIDDENBYTE</span></code>) have been replaced with <code class="docutils literal notranslate"><span class="pre">0xCD</span></code>, <code class="docutils literal notranslate"><span class="pre">0xDD</span></code>
|
||
and <code class="docutils literal notranslate"><span class="pre">0xFD</span></code> to use the same values than Windows CRT debug <code class="docutils literal notranslate"><span class="pre">malloc()</span></code>
|
||
and <code class="docutils literal notranslate"><span class="pre">free()</span></code>.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</div>
|
||
<div class="section" id="the-pymalloc-allocator">
|
||
<span id="pymalloc"></span><h2>The pymalloc allocator<a class="headerlink" href="#the-pymalloc-allocator" title="Permalink to this headline">¶</a></h2>
|
||
<p>Python has a <em>pymalloc</em> allocator optimized for small objects (smaller or equal
|
||
to 512 bytes) with a short lifetime. It uses memory mappings called “arenas”
|
||
with a fixed size of 256 KiB. It falls back to <a class="reference internal" href="#c.PyMem_RawMalloc" title="PyMem_RawMalloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawMalloc()</span></code></a> and
|
||
<a class="reference internal" href="#c.PyMem_RawRealloc" title="PyMem_RawRealloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_RawRealloc()</span></code></a> for allocations larger than 512 bytes.</p>
|
||
<p><em>pymalloc</em> is the <a class="reference internal" href="#default-memory-allocators"><span class="std std-ref">default allocator</span></a> of the
|
||
<a class="reference internal" href="#c.PYMEM_DOMAIN_MEM" title="PYMEM_DOMAIN_MEM"><code class="xref c c-data docutils literal notranslate"><span class="pre">PYMEM_DOMAIN_MEM</span></code></a> (ex: <a class="reference internal" href="#c.PyMem_Malloc" title="PyMem_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMem_Malloc()</span></code></a>) and
|
||
<a class="reference internal" href="#c.PYMEM_DOMAIN_OBJ" title="PYMEM_DOMAIN_OBJ"><code class="xref c c-data docutils literal notranslate"><span class="pre">PYMEM_DOMAIN_OBJ</span></code></a> (ex: <a class="reference internal" href="#c.PyObject_Malloc" title="PyObject_Malloc"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Malloc()</span></code></a>) domains.</p>
|
||
<p>The arena allocator uses the following functions:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="xref c c-func docutils literal notranslate"><span class="pre">VirtualAlloc()</span></code> and <code class="xref c c-func docutils literal notranslate"><span class="pre">VirtualFree()</span></code> on Windows,</p></li>
|
||
<li><p><code class="xref c c-func docutils literal notranslate"><span class="pre">mmap()</span></code> and <code class="xref c c-func docutils literal notranslate"><span class="pre">munmap()</span></code> if available,</p></li>
|
||
<li><p><code class="xref c c-func docutils literal notranslate"><span class="pre">malloc()</span></code> and <code class="xref c c-func docutils literal notranslate"><span class="pre">free()</span></code> otherwise.</p></li>
|
||
</ul>
|
||
<div class="section" id="customize-pymalloc-arena-allocator">
|
||
<h3>Customize pymalloc Arena Allocator<a class="headerlink" href="#customize-pymalloc-arena-allocator" title="Permalink to this headline">¶</a></h3>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.4.</span></p>
|
||
</div>
|
||
<dl class="type">
|
||
<dt id="c.PyObjectArenaAllocator">
|
||
<code class="descname">PyObjectArenaAllocator</code><a class="headerlink" href="#c.PyObjectArenaAllocator" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Structure used to describe an arena allocator. The structure has
|
||
three fields:</p>
|
||
<table class="docutils align-center">
|
||
<colgroup>
|
||
<col style="width: 56%" />
|
||
<col style="width: 44%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Field</p></th>
|
||
<th class="head"><p>Meaning</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*ctx</span></code></p></td>
|
||
<td><p>user context passed as first argument</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">void*</span> <span class="pre">alloc(void</span> <span class="pre">*ctx,</span> <span class="pre">size_t</span> <span class="pre">size)</span></code></p></td>
|
||
<td><p>allocate an arena of size bytes</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">free(void</span> <span class="pre">*ctx,</span> <span class="pre">size_t</span> <span class="pre">size,</span> <span class="pre">void</span> <span class="pre">*ptr)</span></code></p></td>
|
||
<td><p>free an arena</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyObject_GetArenaAllocator">
|
||
<code class="descname">PyObject_GetArenaAllocator</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyObjectArenaAllocator" title="PyObjectArenaAllocator">PyObjectArenaAllocator</a><em> *allocator</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_GetArenaAllocator" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Get the arena allocator.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyObject_SetArenaAllocator">
|
||
<code class="descname">PyObject_SetArenaAllocator</code><span class="sig-paren">(</span><a class="reference internal" href="#c.PyObjectArenaAllocator" title="PyObjectArenaAllocator">PyObjectArenaAllocator</a><em> *allocator</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_SetArenaAllocator" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Set the arena allocator.</p>
|
||
</dd></dl>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="section" id="tracemalloc-c-api">
|
||
<h2>tracemalloc C API<a class="headerlink" href="#tracemalloc-c-api" title="Permalink to this headline">¶</a></h2>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">New in version 3.7.</span></p>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="examples">
|
||
<span id="memoryexamples"></span><h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
|
||
<p>Here is the example from section <a class="reference internal" href="#memoryoverview"><span class="std std-ref">Overview</span></a>, rewritten so that the
|
||
I/O buffer is allocated from the Python heap by using the first function set:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span> <span class="o">*</span><span class="n">res</span><span class="p">;</span>
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">buf</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span> <span class="n">PyMem_Malloc</span><span class="p">(</span><span class="n">BUFSIZ</span><span class="p">);</span> <span class="cm">/* for I/O */</span>
|
||
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">buf</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">PyErr_NoMemory</span><span class="p">();</span>
|
||
<span class="cm">/* ...Do some I/O operation involving buf... */</span>
|
||
<span class="n">res</span> <span class="o">=</span> <span class="n">PyBytes_FromString</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
|
||
<span class="n">PyMem_Free</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span> <span class="cm">/* allocated with PyMem_Malloc */</span>
|
||
<span class="k">return</span> <span class="n">res</span><span class="p">;</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The same code using the type-oriented function set:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span> <span class="o">*</span><span class="n">res</span><span class="p">;</span>
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">buf</span> <span class="o">=</span> <span class="n">PyMem_New</span><span class="p">(</span><span class="kt">char</span><span class="p">,</span> <span class="n">BUFSIZ</span><span class="p">);</span> <span class="cm">/* for I/O */</span>
|
||
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">buf</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">PyErr_NoMemory</span><span class="p">();</span>
|
||
<span class="cm">/* ...Do some I/O operation involving buf... */</span>
|
||
<span class="n">res</span> <span class="o">=</span> <span class="n">PyBytes_FromString</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
|
||
<span class="n">PyMem_Del</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span> <span class="cm">/* allocated with PyMem_New */</span>
|
||
<span class="k">return</span> <span class="n">res</span><span class="p">;</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that in the two examples above, the buffer is always manipulated via
|
||
functions belonging to the same set. Indeed, it is required to use the same
|
||
memory API family for a given memory block, so that the risk of mixing different
|
||
allocators is reduced to a minimum. The following code sequence contains two
|
||
errors, one of which is labeled as <em>fatal</em> because it mixes two different
|
||
allocators operating on different heaps.</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">char</span> <span class="o">*</span><span class="n">buf1</span> <span class="o">=</span> <span class="n">PyMem_New</span><span class="p">(</span><span class="kt">char</span><span class="p">,</span> <span class="n">BUFSIZ</span><span class="p">);</span>
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">buf2</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span> <span class="n">malloc</span><span class="p">(</span><span class="n">BUFSIZ</span><span class="p">);</span>
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">buf3</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span> <span class="n">PyMem_Malloc</span><span class="p">(</span><span class="n">BUFSIZ</span><span class="p">);</span>
|
||
<span class="p">...</span>
|
||
<span class="n">PyMem_Del</span><span class="p">(</span><span class="n">buf3</span><span class="p">);</span> <span class="cm">/* Wrong -- should be PyMem_Free() */</span>
|
||
<span class="n">free</span><span class="p">(</span><span class="n">buf2</span><span class="p">);</span> <span class="cm">/* Right -- allocated via malloc() */</span>
|
||
<span class="n">free</span><span class="p">(</span><span class="n">buf1</span><span class="p">);</span> <span class="cm">/* Fatal -- should be PyMem_Del() */</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>In addition to the functions aimed at handling raw memory blocks from the Python
|
||
heap, objects in Python are allocated and released with <a class="reference internal" href="allocation.html#c.PyObject_New" title="PyObject_New"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_New()</span></code></a>,
|
||
<a class="reference internal" href="allocation.html#c.PyObject_NewVar" title="PyObject_NewVar"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_NewVar()</span></code></a> and <a class="reference internal" href="allocation.html#c.PyObject_Del" title="PyObject_Del"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_Del()</span></code></a>.</p>
|
||
<p>These will be explained in the next chapter on defining and implementing new
|
||
object types in C.</p>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Memory Management</a><ul>
|
||
<li><a class="reference internal" href="#overview">Overview</a></li>
|
||
<li><a class="reference internal" href="#raw-memory-interface">Raw Memory Interface</a></li>
|
||
<li><a class="reference internal" href="#memory-interface">Memory Interface</a></li>
|
||
<li><a class="reference internal" href="#object-allocators">Object allocators</a></li>
|
||
<li><a class="reference internal" href="#default-memory-allocators">Default Memory Allocators</a></li>
|
||
<li><a class="reference internal" href="#customize-memory-allocators">Customize Memory Allocators</a></li>
|
||
<li><a class="reference internal" href="#the-pymalloc-allocator">The pymalloc allocator</a><ul>
|
||
<li><a class="reference internal" href="#customize-pymalloc-arena-allocator">Customize pymalloc Arena Allocator</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#tracemalloc-c-api">tracemalloc C API</a></li>
|
||
<li><a class="reference internal" href="#examples">Examples</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="init.html"
|
||
title="previous chapter">Initialization, Finalization, and Threads</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="objimpl.html"
|
||
title="next chapter">Object Implementation Support</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.7/Doc/c-api/memory.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="objimpl.html" title="Object Implementation Support"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="init.html" title="Initialization, Finalization, and Threads"
|
||
>previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python/C API Reference Manual</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||
<br />
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
Last updated on Jul 13, 2019.
|
||
<a href="../bugs.html">Found a bug</a>?
|
||
<br />
|
||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |