I am trying to update/alter two columns-comment and id in a table called xxx using postgresql. Though the compiler does not show any errors but Valgrind gives major errors. The code is:
int main()
{
PGconn *conn;
PGresult *res;
int i=0,nFields=0,row=0,col=0;
conn = PQconnectdb("dbname=test1 host=localhost user=postgres password=yyy");
if(PQstatus(conn) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database \"%s\" failed.\n", PQerrorMessage(conn));
fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}
res = PQexec(conn, "IF COL_LENGTH('xxx','comment') IS NULL");
if(res)
res = PQexec(conn, "ALTER TABLE xxx ADD comment VARCHAR(500)");
else
res = PQexec(conn, "UPDATE TABLE xxx ADD comment VARCHAR(500)");
res = PQexec(conn, "IF COL_LENGTH('xxx','id') IS NULL");
if(res)
res = PQexec(conn, "ALTER TABLE xxx ADD id VARCHAR(50)");
else
res = PQexec(conn, "UPDATE TABLE xxx ADD id VARCHAR(50)");
res = PQexec(conn, "SELECT * FROM xxx");
if((!res) || (PQresultStatus(res) != PGRES_TUPLES_OK))
{
fprintf(stderr, "SELECT command did not return tuples properly\n");
PQclear(res);
}
PQclear(res);
PQfinish(conn);
return 0;
}
Valgrind gives the following errors:
$ valgrind --track-origins=yes --leak-check=full ./output xaa
==4525== Memcheck, a memory error detector
==4525== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4525== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==4525== Command: ./Gwidd_uniprot_map2 xaa
==4525==
--4525-- ./Gwidd_uniprot_map2:
--4525-- dSYM directory has wrong UUID; consider using --dsymutil=yes
==4525==
==4525== HEAP SUMMARY:
==4525== in use at exit: 262,994 bytes in 751 blocks
==4525== total heap usage: 1,012 allocs, 261 frees, 345,158 bytes allocated
==4525==
==4525== 2,248 (200 direct, 2,048 indirect) bytes in 1 blocks are definitely lost in loss record 400 of 414
==4525== at 0x100011345: malloc (vg_replace_malloc.c:236)
==4525== by 0x10007B7E0: PQmakeEmptyPGresult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008DF30: pqGetErrorNotice3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008CC00: pqParseInput3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007ECD9: parseInput (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007EE3F: PQgetResult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F6F1: PQexecFinish (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F1DC: PQexec (in /usr/lib/libpq.5.dylib)
==4525== by 0x10000199A: main (in ./Gwidd_uniprot_map2)
==4525==
==4525== 2,248 (200 direct, 2,048 indirect) bytes in 1 blocks are definitely lost in loss record 401 of 414
==4525== at 0x100011345: malloc (vg_replace_malloc.c:236)
==4525== by 0x10007B7E0: PQmakeEmptyPGresult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008DF30: pqGetErrorNotice3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008CC00: pqParseInput3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007ECD9: parseInput (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007EE3F: PQgetResult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F6F1: PQexecFinish (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F1DC: PQexec (in /usr/lib/libpq.5.dylib)
==4525== by 0x1000019B5: main (in ./Gwidd_uniprot_map2)
==4525==
==4525== 2,248 (200 direct, 2,048 indirect) bytes in 1 blocks are definitely lost in loss record 402 of 414
==4525== at 0x100011345: malloc (vg_replace_malloc.c:236)
==4525== by 0x10007B7E0: PQmakeEmptyPGresult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008DF30: pqGetErrorNotice3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008CC00: pqParseInput3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007ECD9: parseInput (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007EE3F: PQgetResult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F6F1: PQexecFinish (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F1DC: PQexec (in /usr/lib/libpq.5.dylib)
==4525== by 0x1000019DF: main (in ./Gwidd_uniprot_map2)
==4525==
==4525== 2,248 (200 direct, 2,048 indirect) bytes in 1 blocks are definitely lost in loss record 403 of 414
==4525== at 0x100011345: malloc (vg_replace_malloc.c:236)
==4525== by 0x10007B7E0: PQmakeEmptyPGresult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008DF30: pqGetErrorNotice3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10008CC00: pqParseInput3 (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007ECD9: parseInput (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007EE3F: PQgetResult (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F6F1: PQexecFinish (in /usr/lib/libpq.5.dylib)
==4525== by 0x10007F1DC: PQexec (in /usr/lib/libpq.5.dylib)
==4525== by 0x1000019FA: main (in ./Gwidd_uniprot_map2)
==4525==
==4525== LEAK SUMMARY:
==4525== definitely lost: 800 bytes in 4 blocks
==4525== indirectly lost: 8,192 bytes in 4 blocks
==4525== possibly lost: 0 bytes in 0 blocks
==4525== still reachable: 254,002 bytes in 743 blocks
==4525== suppressed: 0 bytes in 0 blocks
==4525== Reachable blocks (those to which a pointer was found) are not shown.
==4525== To see them, rerun with: --leak-check=full --show-reachable=yes
==4525==
==4525== For counts of detected and suppressed errors, rerun with: -v
==4525== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Please provide suggestions to solve the problem.
Modification of the above code:
int main()
{
PGconn *conn;
PGresult *res;
int i=0,nFields=0,row=0,col=0;
conn = PQconnectdb("dbname=test1 host=localhost user=postgres password=madhurima");
if(PQstatus(conn) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database \"%s\" failed.\n", PQerrorMessage(conn));
fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}
res = PQexec(conn, "IF COL_LENGTH('protein_sequence','comment') IS NULL");
PQclear(res);
if(res)
{
res = PQexec(conn, "ALTER TABLE protein_sequence ADD comment VARCHAR(500)");
PQclear(res);
}
else
{
res = PQexec(conn, "UPDATE TABLE protein_sequence ADD comment VARCHAR(500)");
PQclear(res);
}
res = PQexec(conn, "IF COL_LENGTH('protein_sequence','uniprotid') IS NULL");
PQclear(res);
if(res)
{
res = PQexec(conn, "ALTER TABLE protein_sequence ADD uniprotid VARCHAR(50)");
PQclear(res);
}
else
{
res = PQexec(conn, "UPDATE TABLE protein_sequence ADD uniprotid VARCHAR(50)");
PQclear(res);
}
res = PQexec(conn, "SELECT * FROM protein_sequence");
PQclear(res);
if((!res) || (PQresultStatus(res) != PGRES_TUPLES_OK))
{
fprintf(stderr, "SELECT command did not return tuples properly\n");
PQclear(res);
}
PQclear(res);
PQfinish(conn);
return 0;
}
New errors from Valgrind:
==9234== Memcheck, a memory error detector
==9234== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==9234== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==9234== Command: ./Gwidd_uniprot_map2 xaa
==9234==
--9234-- ./Gwidd_uniprot_map2:
--9234-- dSYM directory has wrong UUID; consider using --dsymutil=yes
==9234== Invalid read of size 4
==9234== at 0x1000804CF: PQresultStatus (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A3B: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dff78 is 40 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid read of size 4
==9234== at 0x10007CCCD: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dffe8 is 152 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid read of size 8
==9234== at 0x10007CCE2: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dffe0 is 144 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid read of size 8
==9234== at 0x10007CD26: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013e0008 is 184 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid read of size 8
==9234== at 0x10007CD3F: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dff60 is 16 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid write of size 8
==9234== at 0x10007CD5D: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dff58 is 8 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid write of size 8
==9234== at 0x10007CD69: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dff60 is 16 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid write of size 8
==9234== at 0x10007CD75: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dff70 is 32 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid write of size 8
==9234== at 0x10007CD81: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dfff8 is 168 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid write of size 8
==9234== at 0x10007CD90: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dffe0 is 144 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid write of size 4
==9234== at 0x10007CD9F: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dffe8 is 152 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234== Invalid free() / delete / delete[]
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A72: main (in ./Gwidd_uniprot_map2)
==9234== Address 0x1013dff50 is 0 bytes inside a block of size 200 free'd
==9234== at 0x100010E9F: free (vg_replace_malloc.c:366)
==9234== by 0x10007CDB4: PQclear (in /usr/lib/libpq.5.dylib)
==9234== by 0x100001A2B: main (in ./Gwidd_uniprot_map2)
==9234==
==9234==
==9234== HEAP SUMMARY:
==9234== in use at exit: 254,002 bytes in 743 blocks
==9234== total heap usage: 1,012 allocs, 270 frees, 345,158 bytes allocated
==9234==
==9234== LEAK SUMMARY:
==9234== definitely lost: 0 bytes in 0 blocks
==9234== indirectly lost: 0 bytes in 0 blocks
==9234== possibly lost: 0 bytes in 0 blocks
==9234== still reachable: 254,002 bytes in 743 blocks
==9234== suppressed: 0 bytes in 0 blocks
==9234== Reachable blocks (those to which a pointer was found) are not shown.
==9234== To see them, rerun with: --leak-check=full --show-reachable=yes
==9234==
==9234== For counts of detected and suppressed errors, rerun with: -v
==9234== ERROR SUMMARY: 12 errors from 12 contexts (suppressed: 0 from 0)
Consider the following snippet from your code:
res = PQexec(conn, "IF COL_LENGTH('xxx','comment') IS NULL");
if(res)
res = PQexec(conn, "ALTER TABLE xxx ADD comment VARCHAR(500)");
else
res = PQexec(conn, "UPDATE TABLE xxx ADD comment VARCHAR(500)");
There are several things wrong here:
You are never calling PQclear on the result of the first PQexec, which leaves a memory leak. Remember that res holds a pointer to the returned structure which is dynamically allocated. This is what valgrind is complaining about.
You are not correctly checking the result of the first query. Just checking that the return from PGexec was not null says nothing about the result of executing the command, it only confirms that libpq was able to allocate enough memory to return a result structure.
You also did not check for errors. You should call PQresultStatus to determine if the query was executed successfully.
If you did check for errors I suspect you would have found out that the SQL you are trying to execute. There is no IF statement in SQL. There is one in PL/pgSQL but that is inside the context of a stored procedure.
See the libpq documentation for more details on the correct way to call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With