Recently I wrote an application that accesses a Postgres DB via libpqxx, and it leaks memory badly. Even this simple test program, which is based on the example at http://pqxx.org/devprojects/libpqxx/doc/4.0/html/Reference/a00001.html leaks like no tomorrow.
(Edit: I added calls to commit() and clear() in response to suggestions. Same leakiness.)
#include <iostream>
#include <pqxx/pqxx>
#include <string>
#include <stdio.h>
int main()
{
try
{
pqxx::connection c("user=postgres");
int i = 0;
while(true)
{
pqxx::work w(c);
pqxx::result r = w.exec("SELECT 1");
w.commit();
i++;
if ( i % 1000 == 0 )
printf( "Cycle %d\n", i );
r.clear();
} //while
} //try
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
return 1;
} //catch
} //main
After about 75,000 cycles of the loop, top shows 206Mb of virtual memory usage, and it keeps climbing. I ran a similar test program with 5000 cycles through valgrind and got this:
==1647== 13,732,155 (219,868 direct, 13,512,287 indirect) bytes in 4,997 blocks are definitely lost in loss record 12 of 12
==1647== at 0x40060D5: operator new(unsigned int) (vg_replace_malloc.c:214)
==1647== by 0x404C0A9: pqxx::result::result(pg_result*, int, std::string const&, int) (in /usr/lib/libpqxx-4.0.so)
==1647== by 0x40309EF: pqxx::connection_base::make_result(pg_result*, std::string const&) (in /usr/lib/libpqxx-4.0.so)
==1647== by 0x4036D65: ??? (in /usr/lib/libpqxx-4.0.so)
==1647== by 0x405EFD6: pqxx::transaction_base::DirectExec(char const*, int) (in /usr/lib/libpqxx-4.0.so)
==1647== by 0x40416EA: pqxx::dbtransaction::do_exec(char const*) (in /usr/lib/libpqxx-4.0.so)
==1647== by 0x40618FA: pqxx::transaction_base::exec(std::string const&, std::string const&) (in /usr/lib/libpqxx-4.0.so)
==1647== by 0x80498F8: main (dbtest.cpp:21)
Any idea what's going on? It's very difficult to accept that a widely used library like libpqxx would have such a severe bug, so what might I be doing wrong here?
Configuration details:
- OS: Linux 2.6.18-238.el5
- gcc version 4.4.0
- libpqxx 4.0
- postgres 9.2
(Final edit: I found it easier to replace libpqxx with libpq than to keep investigating this memory leak.)