Thread: when to use pfree?

when to use pfree?

From
Ron Peterson
Date:
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/

Re: when to use pfree?

From
Ron Peterson
Date:
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 );



Re: when to use pfree?

From
Tom Lane
Date:
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