Memory leak when using sqlite3 with C++
<p>The program writes into SQLite database, the messages are received through a wireless module. But somehow there is a memory leak every time a message is received and written to the database, after about 10 000 writes the program is using 1GB of memory. </p>

<p>The documentation for <a href="https://www.sqlite.org/cintro.html" rel="nofollow">SQLite3 with C++</a> says that memory leaks are prevented with <code>sqlite3_finalize()</code> and <code>sqlite3_close()</code> which are present:</p>

<pre><code>#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;sstream&gt;
#include "sqlite3.h"

using namespace std;

#define DB "test.db"
sqlite3 *dbfile;

bool connectDB();
void disonnectDB();
int insOrUpdate(string s);
int select(string s);

struct messageStruct_t {
  float value;
};

bool isOpenDB = false;

int main() {
  int counter = 0;
  while (1) {
    int header = 1;
    int message = rand() % 3;

    if (message) {
      counter ++;

      switch (header) {

      case 1: {
        messageStruct_t recMessage;
        recMessage.value = 55;
        int receivedSendersID = 2;

        //SQL query to get foreign key
        stringstream strm_select;
        strm_select &lt;&lt; "SELECT id FROM table1 WHERE sendersID="
                    &lt;&lt; receivedSendersID;
        string s_select = strm_select.str();
        cout &lt;&lt; "SQL query: " &lt;&lt; s_select &lt;&lt; endl;
        int sendersID = select(s_select);
        cout &lt;&lt; "Sender's ID: " &lt;&lt; sendersID &lt;&lt; endl;


        if (sendersID == 0) {
          cout &lt;&lt; "Error: Sender doesn't exist\n";
        } else {
          stringstream strm_insert;
          strm_insert &lt;&lt; "INSERT into table2(id,value,sender_id) values("
                      &lt;&lt; counter &lt;&lt; ", "
                      &lt;&lt; recMessage.value &lt;&lt; ", " &lt;&lt; sendersID &lt;&lt; ")";
          string s_insert = strm_insert.str();
          cout &lt;&lt; "SQL query: " &lt;&lt; s_insert &lt;&lt; endl;
          insOrUpdate(s_insert);
          cout &lt;&lt; "Recorded data: " &lt;&lt; recMessage.value &lt;&lt; endl;
        }
      }

      default: {
        break;
      }

      }
    }
  }
}

bool connectDB () {
  if (sqlite3_open(DB, &amp;dbfile) == SQLITE_OK) {
    isOpenDB = true;
    return true;
  }
  return false;
}

void disonnectDB () {
  if ( isOpenDB == true ) {
    sqlite3_close(dbfile);
  }
}

int insOrUpdate(string s) {
  if (!connectDB()) {
    return 0;
  }

  char *str = &amp;s[0];
  sqlite3_stmt *statement;
  int result;
  const char *query = str;

  if (sqlite3_prepare(dbfile, query, -1, &amp;statement, 0) == SQLITE_OK) {
    result = sqlite3_step(statement);
    //the documentation says that this destroys the statement and prevents memory leaks
    sqlite3_finalize(statement);
    return result;
  }
  //and this destroys the db object and prevents memory leaks
  disonnectDB();
  return 0;
}

int select(string s) {
  if (!connectDB()) {
    return 0;
  }

  char *str = &amp;s[0];
  sqlite3_stmt *statement;
  const char *query = str;
  string returned;
  if (sqlite3_prepare(dbfile, query, -1, &amp;statement, 0) == SQLITE_OK) {
    int ctotal = sqlite3_column_count(statement);
    int res = 0;

    while (1) {
      res = sqlite3_step(statement);
      if (res == SQLITE_ROW) {
        for (int i = 0; i &lt; ctotal; i++) {
          string s = (char*)sqlite3_column_text(statement, i);
          cout &lt;&lt; s &lt;&lt; " ";
          returned = s;
        }
        cout &lt;&lt; endl;
      }
      if (res == SQLITE_DONE || res == SQLITE_ERROR) {
        cout &lt;&lt; "done " &lt;&lt; endl;
        break;
      }
    }
  } else {
    cout &lt;&lt; "Can't prepare" &lt;&lt; endl;
    return 0;
  }
  sqlite3_finalize(statement);
  disonnectDB();

  int result;
  stringstream convert(returned);
  if (!(convert &gt;&gt; result)) {
    result = 0;
  }

  return result;
}
</code></pre>

<hr>

<pre><code>CREATE TABLE table1 (
id INTEGER NOT NULL,
sendersID INTEGER,
PRIMARY KEY (id)
);
CREATE TABLE table2 (
id INTEGER NOT NULL,
value FLOAT,
sender_id INTEGER,
FOREIGN KEY(sender_id) REFERENCES table1 (id)
);

INSERT INTO table1(sendersID) values(2);
</code></pre>