SPI_execute
や類似の関数によって生成された行セットを解放する
PostgreSQLは、メモリコンテキスト内にメモリを確保します。
これは、様々な場所で、必要な有効期間がそれぞれ異なるような割り当てを管理する便利な方法を提供します。
コンテキストを破壊することで、そこで割り当てられた全てのメモリを解放します。
したがって、メモリリークを防ぐための個々のオブジェクトの追跡を維持することは不要です。
その代わり、相対的に少量のコンテキストを管理する必要があります。
palloc
と関連する関数は「現在の」コンテキストからメモリを確保します。
SPI_connect
は新しくメモリコンテキストを作成し、それを現在のコンテキストとします。
SPI_finish
は直前の現在のメモリコンテキストを戻し、SPI_connect
で作成されたコンテキストを破壊します。
これらの動作により、C関数内で割り当てが行われる一時的なメモリがC関数の終了時に回収され、メモリリークが防止されることが保証されます。
しかし、(参照渡しのデータ型の値といった)C関数が割り当てられたメモリ内のオブジェクトを返す必要がある場合、少なくともSPIに接続していない期間は、palloc
を使用してメモリを確保することができません。
これを試行すると、そのオブジェクトはSPI_finish
で解放されてしまい、C関数は正しく動作しないでしょう。
この問題を解決するには、SPI_palloc
を使用して、戻り値となるオブジェクト用のメモリを確保してください。
SPI_palloc
は「上位エクゼキュータコンテキスト」内にメモリを割り当てます。
このメモリコンテキストは、SPI_connect
が呼び出された時点において現在のコンテキストだったものであり、C関数の戻り値用のコンテキストとしてまさに正しいものです。
この章で説明されているほかのユーティリティ関数のいくつかも、上位エクゼキュータコンテキスト内で作成されたオブジェクトを返します。
SPI_connect
が呼び出されると、SPI_connect
によって作成されるC関数固有のコンテキストが現在のコンテキストに作成されます。
palloc
、repalloc
、SPIユーティリティ関数(この章で説明されているものは除きます)によって作成される割り当ては全て、このコンテキスト内に作成されます。
C関数がSPIマネージャから(SPI_finish
経由で)切断した時、現在のコンテキストは上位エクゼキュータコンテキストに戻され、C関数のメモリコンテキスト内で割り当てられたメモリは全て解放され、二度と使用することができません。