title: Memory leak when using sqlite3 with C++
body: <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>