SPI_execute或类似函数创建的一行集 PostgreSQL 在内存上下文中分配内存,这是一种管理在不同时间生存期不同的地方进行分配的便捷方法。销毁一个上下文会释放其中分配的所有内存。因此,不必跟踪单个对象以避免内存泄漏;只需管理相对较少数量的上下文即可。palloc及相关函数从“当前”上下文中分配内存。
SPI_connect 创建一个新的内存上下文并将其设为当前。 SPI_finish 恢复先前的当前内存上下文并销毁由 SPI_connect 创建的上下文。这些操作可确保在 C 函数退出时回收在 C 函数中进行的临时内存分配,从而避免内存泄漏。
但是,如果您的 C 函数需要返回分配内存中的对象(例如,传递引用数据类型的返回值),则不能使用 palloc 分配该内存,至少在连接到 SPI 时不行。如果尝试这样做,对象将在 SPI_finish 中被释放,您的 C 函数将无法可靠运行。要解决此问题,请使用 SPI_palloc 为返回对象分配内存。 SPI_palloc 在“上层执行器上下文”中分配内存,也就是说,当调用 SPI_connect 时当前存在的内存上下文,这正是从 C 函数返回值所需要的正确上下文。本节中描述的许多其他实用函数也返回在上层执行器上下文中创建的对象。
当调用 SPI_connect 时,由 SPI_connect 创建的 C 函数的私有上下文被设为当前上下文。由 palloc、repalloc 或 SPI 实用函数(本节所述情况除外)进行的所有分配都将在此上下文中进行。当 C 函数通过 SPI_finish 与 SPI 管理器断开连接时,当前上下文将恢复为上层执行器上下文,并且在 C 函数内存上下文中进行的所有分配都将被释放,不再可用。