diff options
author | John Ankarström <john@ankarstrom.se> | 2022-07-19 12:16:15 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2022-07-19 12:16:15 +0200 |
commit | 34c32802122ff80e79d850d44cbc84624d9a5840 (patch) | |
tree | b03f55581dda8ad8560ca8e0fd2f2eb341392345 /c/pl.cpp | |
parent | 2a7f4bcd4c04d0e48e580c4b11a94174bc5b09ae (diff) | |
download | EpisodeBrowser-34c32802122ff80e79d850d44cbc84624d9a5840.tar.gz |
Fix Prolog memory leaks.
Apparently foreign frames ARE needed when calling Prolog from C. The
official documentation is very terse and could make this clearer.
To summarize, whenever a term is created (e.g., PL_new_term_refs), its
reference count is increased by one. It is garbage-collected when its
reference count hits zero. But the reference count is never decreased
unless (a) control returns to Prolog after executing a foreign
predicate -- which does not happen in my application -- or (b) the
foreign frame in which the term was created is closed.
In other words, terms must be created within a foreign frame. This is
achieved by initializing a Frame object before creating the term and
destroying it once the term has served its purpose.
The destructor for Frame does not DISCARD the frame, only CLOSE it.
The former would also invalidate all data bound by the terms, which is
usually undesirable.
Diffstat (limited to 'c/pl.cpp')
-rw-r--r-- | c/pl.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
@@ -3,6 +3,31 @@ #include "pl.h" +Frame::Frame() +{ + m_f = PL_open_foreign_frame(); +} + +Frame::~Frame() +{ + PL_close_foreign_frame(m_f); +} + +void Frame::Close() +{ + PL_close_foreign_frame(m_f); +} + +void Frame::Discard() +{ + PL_discard_foreign_frame(m_f); +} + +void Frame::Rewind() +{ + PL_rewind_foreign_frame(m_f); +} + Query::Query(const module_t ctx, const predicate_t p, const term_t t0) { m_q = PL_open_query(ctx, PL_Q_CATCH_EXCEPTION, p, t0); @@ -50,6 +75,7 @@ int PL_get_tchars(const term_t t, TCHAR** const pTsz, const int iFlags) int Plx(const char* const szMod, const char* const szPred) { + Frame f; const term_t t = PL_new_term_refs(0); Query q(NULL, PL_predicate(szPred, 0, szMod), t); return q.NextSolution(); |