Lifetime of PQexecPrepared() returned value

Started by Igor Korotover 8 years ago6 messagesgeneral
Jump to latest
#1Igor Korot
ikorot01@gmail.com

Hi, ALL,
I have a following piece of code:

[code]
PGresult *res = PQexecPrepared();
status = PQresultStatue( res );
if( status == PGRES_TUPLES_OK )
{
for( int j = 0; j < PQntuples( res ); j++ )
{
char *foo = PQgetValue( res, j, 0 );
char *bar = PQgetValue( res, j, 1 );
MyObject *obj = new MyObject( foo, bar );
if( SetAdditionalProperties( obj ) )
{
result = 1;
break;
}
}
PQclear( res );
}

int SetAdditionalProperties(MyObject &obj)
{
// a call to PQexecParams() here
}
[/code]

If the call to SetAdditionalProperties() fails, I get a crash on
PQclear(), stating that
the pointer is not allocated.

Am I missing something? How do I fix the crash?

Thank you.

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#2Michael Paquier
michael@paquier.xyz
In reply to: Igor Korot (#1)
Re: Lifetime of PQexecPrepared() returned value

On Fri, Aug 4, 2017 at 9:12 PM, Igor Korot <ikorot01@gmail.com> wrote:

Am I missing something? How do I fix the crash?

Based on what I can see here, I see nothing wrong. Now it is hard to
reach any conclusion with the limited information you are providing.
--
Michael

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#3Igor Korot
ikorot01@gmail.com
In reply to: Michael Paquier (#2)
Re: Lifetime of PQexecPrepared() returned value

Hi, Michael,

On Fri, Aug 4, 2017 at 3:26 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

On Fri, Aug 4, 2017 at 9:12 PM, Igor Korot <ikorot01@gmail.com> wrote:

Am I missing something? How do I fix the crash?

Based on what I can see here, I see nothing wrong. Now it is hard to
reach any conclusion with the limited information you are providing.

Same here.
I will give the full code when I get home.

Thank you.

--
Michael

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Igor Korot (#1)
Re: Lifetime of PQexecPrepared() returned value

Igor Korot <ikorot01@gmail.com> writes:

I have a following piece of code:

[code]
PGresult *res = PQexecPrepared();
status = PQresultStatue( res );
if( status == PGRES_TUPLES_OK )
{
for( int j = 0; j < PQntuples( res ); j++ )
{
char *foo = PQgetValue( res, j, 0 );
char *bar = PQgetValue( res, j, 1 );
MyObject *obj = new MyObject( foo, bar );
if( SetAdditionalProperties( obj ) )
{
result = 1;
break;
}
}
PQclear( res );
}

What I'm wondering about is whether the MyObject constructor is making
copies of the strings it's passed, or whether it thinks it can just hold
onto those pointers. The pointers would be dangling once you do PQclear.
Now, if the MyObject has gone out of scope and been destroyed, which
this coding suggests would happen, then that shouldn't matter ... but
maybe the pointers got copied to somewhere longer-lived? Anyway, there's
nothing visibly wrong with what you showed us, so the problem is somewhere
else.

regards, tom lane

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#5Igor Korot
ikorot01@gmail.com
In reply to: Tom Lane (#4)
Re: Lifetime of PQexecPrepared() returned value

Hi, guys,

On Fri, Aug 4, 2017 at 5:01 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Igor Korot <ikorot01@gmail.com> writes:

I have a following piece of code:

[code]
PGresult *res = PQexecPrepared();
status = PQresultStatue( res );
if( status == PGRES_TUPLES_OK )
{
for( int j = 0; j < PQntuples( res ); j++ )
{
char *foo = PQgetValue( res, j, 0 );
char *bar = PQgetValue( res, j, 1 );
MyObject *obj = new MyObject( foo, bar );
if( SetAdditionalProperties( obj ) )
{
result = 1;
break;
}
}
PQclear( res );
}

What I'm wondering about is whether the MyObject constructor is making
copies of the strings it's passed, or whether it thinks it can just hold
onto those pointers. The pointers would be dangling once you do PQclear.
Now, if the MyObject has gone out of scope and been destroyed, which
this coding suggests would happen, then that shouldn't matter ... but
maybe the pointers got copied to somewhere longer-lived? Anyway, there's
nothing visibly wrong with what you showed us, so the problem is somewhere
else.

I need to deeply apologize.
I cam home yesterday, look at the code again and saw the PQclear()
call in the if()
block.
However it leads to another question - should PQclear set the pointer to NULL?

Sorry for the noise once again and thank you for reading.

regards, tom lane

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Igor Korot (#5)
Re: Lifetime of PQexecPrepared() returned value

Igor Korot <ikorot01@gmail.com> writes:

However it leads to another question - should PQclear set the pointer to NULL?

C doesn't provide any reasonable way to do that. The argument of PQclear
needn't even be an lvalue; for example, if you're not too concerned about
error checking, it's not unreasonable to write

PQclear(PQexec(conn, "some SQL command"));

regards, tom lane

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general