Thread: when to use pfree?
I just encountered a problem with a C function I've been working on where it broke with the error: could not find block containing chunk ... I tracked the problem down to my use of pfree. Apparently my function was not happy attempting to return a result that was built using values that had been pfree'd. Commenting out the indicated section solved my problem. I understand that one of the advantages of palloc is that allocated memory is automatically returned at some point. My question is, when does it make sense to call pfree? I wouldn't have expected the variables I free'd below to still be needed, but apparently they were. So now I'm feeling a little intimidated about using pfree at all. Should I just save a little wear and tear on my keyboard and forgo the use of pfree altogether? aim = TupleDescGetAttInMetadata( td ); ht = BuildTupleFromCStrings( aim, vals); /* make the tuple into a datum */ result = HeapTupleGetDatum( ht ); ... // pfree( rd ); // pfree( vals[0] ); // pfree( vals[1] ); // pfree( vals[2] ); // pfree( vals ); PG_RETURN_DATUM( result ); TIA -- Ron Peterson https://www.yellowbank.com/
On Tue, Nov 07, 2006 at 08:36:45AM -0500, Ron Peterson wrote: > I just encountered a problem with a C function I've been working on > where it broke with the error: > > could not find block containing chunk ... > > I tracked the problem down to my use of pfree. I narrowed the problem down a little bit more. It has nothing to do with the value I'm returning, it's only the call to 'pfree( rd )' below that causes me problems. I did the following, which apparently causes problems. I wrote my own little function which allocates rd (using palloc). char* tp2cp_palloc( char* stringp, const text* textp ) { int len; len = VARSIZE(textp) - VARHDRSZ; stringp = (char*)palloc( len + 1 ); if( ! memcpy( stringp, VARDATA(textp), len ) ) { return NULL; } if( ! memset( stringp + len, '\0', 1 ) ) { return NULL; } return stringp; } Which I call like otherfunc() { char* rd; if( ! tp2cp_palloc( rd, rand_dev ) ) ... pfree( rd ); } Apparently pfree hates that. Should I abandom this idiom altogether? Or is it o.k. to do this if I avoid the call to pfree (i.e. - will the variable be deallocated automatically)? TIA. -- Ron Peterson https://www.yellowbank.com/ > aim = TupleDescGetAttInMetadata( td ); > ht = BuildTupleFromCStrings( aim, vals); > > /* make the tuple into a datum */ > result = HeapTupleGetDatum( ht ); > > ... > > // pfree( rd ); > // pfree( vals[0] ); > // pfree( vals[1] ); > // pfree( vals[2] ); > // pfree( vals ); > > PG_RETURN_DATUM( result );
Ron Peterson <ron.peterson@yellowbank.com> writes: > char* > tp2cp_palloc( char* stringp, const text* textp ) { > int len; > len = VARSIZE(textp) - VARHDRSZ; > stringp = (char*)palloc( len + 1 ); > if( ! memcpy( stringp, VARDATA(textp), len ) ) { return NULL; } > if( ! memset( stringp + len, '\0', 1 ) ) { return NULL; } > return stringp; > } That's simply bizarre coding style. stringp should be a local in tp2cp_palloc, not a passed parameter that you ignore the value of. > Which I call like > otherfunc() { > char* rd; > if( ! tp2cp_palloc( rd, rand_dev ) ) > ... The above does not cause rd to become set in otherfunc(). Had you been using a reasonable set of compiler flags, the compiler would have warned you that rd was uninitialized in otherfunc(). regards, tom lane