Thread: [GENERAL] Lifetime of PQexecPrepared() returned value
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.
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
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
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
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
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