47.3. Memory Management

|        47.3. Memory Management        |              |                                        |                  |                            |
|:-------------------------------------:|--------------|----------------------------------------|------------------|----------------------------|
|[Prev](spi-spi-result-code-string.html)|[Up](spi.html)|Chapter 47. Server Programming Interface|[Home](index.html)| [Next](spi-spi-palloc.html)|

---

## 47.3. Memory Management

[SPI\_palloc](spi-spi-palloc.html) — allocate memory in the upper executor context[SPI\_repalloc](spi-realloc.html) — reallocate memory in the upper executor context[SPI\_pfree](spi-spi-pfree.html) — free memory in the upper executor context[SPI\_copytuple](spi-spi-copytuple.html) — make a copy of a row in the upper executor context[SPI\_returntuple](spi-spi-returntuple.html) — prepare to return a tuple as a Datum[SPI\_modifytuple](spi-spi-modifytuple.html) — create a row by replacing selected fields of a given row[SPI\_freetuple](spi-spi-freetuple.html) — free a row allocated in the upper executor context[SPI\_freetuptable](spi-spi-freetupletable.html) — free a row set created by `SPI_execute` or a similar function[SPI\_freeplan](spi-spi-freeplan.html) — free a previously saved prepared statement

[]() PostgreSQL allocates memory within *memory contexts*, which provide a convenient method of managing allocations made in many different places that need to live for differing amounts of time. Destroying a context releases all the memory that was allocated in it. Thus, it is not necessary to keep track of individual objects to avoid memory leaks; instead only a relatively small number of contexts have to be managed. `palloc` and related functions allocate memory from the “current” context.

`SPI_connect` creates a new memory context and makes it current. `SPI_finish` restores the previous current memory context and destroys the context created by `SPI_connect`. These actions ensure that transient memory allocations made inside your C function are reclaimed at C function exit, avoiding memory leakage.

 However, if your C function needs to return an object in allocated memory (such as a value of a pass-by-reference data type), you cannot allocate that memory using `palloc`, at least not while you are connected to SPI. If you try, the object will be deallocated by `SPI_finish`, and your C function will not work reliably. To solve this problem, use `SPI_palloc` to allocate memory for your return object. `SPI_palloc` allocates memory in the “upper executor context”, that is, the memory context that was current when `SPI_connect` was called, which is precisely the right context for a value returned from your C function. Several of the other utility functions described in this section also return objects created in the upper executor context.

 When `SPI_connect` is called, the private context of the C function, which is created by `SPI_connect`, is made the current context. All allocations made by `palloc`, `repalloc`, or SPI utility functions (except as described in this section) are made in this context. When a C function disconnects from the SPI manager (via `SPI_finish`) the current context is restored to the upper executor context, and all allocations made in the C function memory context are freed and cannot be used any more.

---

|[Prev](spi-spi-result-code-string.html)|  [Up](spi.html)  | [Next](spi-spi-palloc.html)|
|:--------------------------------------|:----------------:|---------------------------:|
|       SPI\_result\_code\_string       |[Home](index.html)|         SPI\_palloc        |

 // \<![CDATA[ \<-- For SVG support if ('WebSocket' in window) { (function() { function refreshCSS() { var sheets = [].slice.call(document.getElementsByTagName("link")); var head = document.getElementsByTagName("head")[0]; for (var i = 0; i \< sheets.length; ++i) { var elem = sheets[i]; head.removeChild(elem); var rel = elem.rel; if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") { var url = elem.href.replace(/(&|\\?)\_cacheOverride=\\d+/, ''); elem.href = url + (url.indexOf('?') \>= 0 ? '&' : '?') + '\_cacheOverride=' + (new Date().valueOf()); } head.appendChild(elem); } } var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://'; var address = protocol + window.location.host + window.location.pathname + '/ws'; var socket = new WebSocket(address); socket.onmessage = function(msg) { if (msg.data == 'reload') window.location.reload(); else if (msg.data == 'refreshcss') refreshCSS(); }; console.log('Live reload enabled.'); })(); } // ]]\>