hello, this segfault is all about PQclear();
according to the docs libpq-exec.html # PQclear Frees the storage associated with the PGresult. Every query result should be freed via PQclear when it is no longer needed. void PQclear(PQresult *res); You can keep a PGresult object around for as long as you need it; it does not go away when you issue a new query, nor even if you close the connection. To get rid of it, you must call PQclear. Failure to do this will result in memory leaks in the frontend application. # I've been playing with the pg example, writing some functions for later inclusion into a project i'm working on when all of a sudden my (incredibly simple) program started to segfault. I checked my code, I let other people check my code, I asked on irc... so far, I can't find bug on my side, so I suppose it's a bug inside PQclear(); This only happened to me when the PQresult *res was just made and hadn't been used before. The example code should give more clarity (please compile as given). Note that using something as res = PQmakeEmptyPGresult(conn, status); PQclear(res); first prevents the program from segfaulting, however, it should have not segfaulted in the first place. version used to compile and run are below. postgres: (PostgreSQL) 7.2.1 glibc: GNU C Library stable release version 2.2.4 Compiled by GNU CC version 2.95.3 20010315 (release).Compiled on a Linux 2.4.14 system on 2001-11-09. gcc: gcc 2.95.3 kernel: Linux pathfinder 2.4.18 #1 SMP Fri Mar 22 17:10:20 CET 2002 i686 unknown build script used to compile this program: rm pqtest gcc -g -Wall -I /opt/postgresql/include -L /opt/postgresql/lib -lpgeasy -lpq pqtest.c -o pqtest I hope you can determine what is going wrong, please keep me informed should you be able to find the cause of this. Kind regards, Eric van Lent note: I also included the code as attachment */ CODE START */ #include <stdio.h> #include <stdlib.h> #include "libpq-fe.h" #include <string.h> int DBinsertCmd(char *, char *, PGconn *, PGresult *); int DBcontrol(); static void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } int main() { int i = 30; int n = 0; char *pghost, *pgport, *pgoptions, *pgtty, *dbName, *login, *pwd, *result; char *tablename = "files"; char *valueOne = "BlahCompatible"; PGconn *conn; PGresult *res; ExecStatusType status; pghost = NULL; /* host name of the backend server */ pgport = NULL; /* port of the backend server */ pgoptions = NULL; /* special options to start up the backend server */ pgtty = NULL; /* debugging tty for the backend server */ dbName = "void"; /* change this to the name of your test * database */ login = "void"; pwd = NULL; /* no pwd for now */ conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, login, pwd); /* make a connection to the database */ if (PQstatus(conn) == CONNECTION_BAD){ /* check to see that the backend connection was successfully made */ fprintf(stderr, "Connection to database '%s' failed.\n", dbName); fprintf(stderr, "%s", PQerrorMessage(conn)); exit_nicely(conn); } //res = PQmakeEmptyPGresult(conn, status); //PQclear(res); if ((DBinsertCmd(tablename, valueOne, conn, res)) == -1) fprintf(stderr,"DBinsertCmd exited with -1\n"); PQclear(res); res = PQexec(conn, "SELECT * FROM files"); while (PQresultStatus(res) == PGRES_TUPLES_OK && n < i){ result = PQgetvalue(res, n, 0); n++; fprintf(stdout,"resultaat: %s\n",result); } PQclear(res); /* PQclear(res) should PQclear PGresult whenever it is no longer needed to avoid memory leaks */ PQfinish(conn); /* close the connection to the database and cleanup */ return 0; /* Though PQfinish(conn1) has called exit(1) */ } int DBinsertCmd(char *tablename, char *valueOne, PGconn *conn, PGresult *res) { char finalCmd[512]; if ((snprintf(finalCmd, 511, "INSERT INTO %s VALUES ('%s')", tablename, valueOne)) == -1){ fprintf(stderr,"DBinsertCmd: WARNING! string \"%s\" was longer then allowed, this should not have happened",finalCmd); return -1; } fprintf(stdout,"%s\n",finalCmd); res = PQexec(conn, finalCmd); if (PQresultStatus(res) != PGRES_COMMAND_OK){ fprintf(stderr, "INSERT command failed: error returned by DB is: %s\n",PQresStatus(PQresultStatus(res))); return -1; } return 1; } /* CODE END */
#include <stdio.h> #include <stdlib.h> #include "libpq-fe.h" #include <string.h> int DBinsertCmd(char *, char *, PGconn *, PGresult *); int DBcontrol(); static void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } int main() { int i = 30; int n = 0; char *pghost, *pgport, *pgoptions, *pgtty, *dbName, *login, *pwd, *result; char *tablename = "files"; char *valueOne = "BlahCompatible"; PGconn *conn; PGresult *res; ExecStatusType status; pghost = NULL; /* host name of the backend server */ pgport = NULL; /* port of the backend server */ pgoptions = NULL; /* special options to start up the backend server */ pgtty = NULL; /* debugging tty for the backend server */ dbName = "void"; /* change this to the name of your test * database */ login = "void"; pwd = NULL; /* no pwd for now */ conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, login, pwd); /* make a connection to the database */ if (PQstatus(conn) == CONNECTION_BAD){ /* check to see that the backend connection was successfully made */ fprintf(stderr, "Connection to database '%s' failed.\n", dbName); fprintf(stderr, "%s", PQerrorMessage(conn)); exit_nicely(conn); } res = PQmakeEmptyPGresult(conn, status); //PQclear(res); if ((DBinsertCmd(tablename, valueOne, conn, res)) == -1) fprintf(stderr,"DBinsertCmd exited with -1\n"); PQclear(res); res = PQexec(conn, "SELECT * FROM files"); while (PQresultStatus(res) == PGRES_TUPLES_OK && n < i){ result = PQgetvalue(res, n, 0); n++; fprintf(stdout,"resultaat: %s\n",result); } PQclear(res); /* PQclear(res) should PQclear PGresult whenever it is no longer needed to avoid memory leaks */ PQfinish(conn); /* close the connection to the database and cleanup */ return 0; /* Though PQfinish(conn1) has called exit(1) */ } int DBinsertCmd(char *tablename, char *valueOne, PGconn *conn, PGresult *res) { char finalCmd[512]; if ((snprintf(finalCmd, 511, "INSERT INTO %s VALUES ('%s')", tablename, valueOne)) == -1){ fprintf(stderr,"DBinsertCmd: WARNING! string \"%s\" was longer then allowed, this should not have happened",finalCmd); return -1; } fprintf(stdout,"%s\n",finalCmd); res = PQexec(conn, finalCmd); if (PQresultStatus(res) != PGRES_COMMAND_OK){ fprintf(stderr, "INSERT command failed: error returned by DB is: %s\n",PQresStatus(PQresultStatus(res))); return -1; } return 1; }
---------------------------(end of broadcast)--------------------------- TIP 3: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly