Обсуждение: Do I have to free storage in a UDF if I raise an error?
If I've done a palloc() to get storage inside a user-defined function and raise an error using ereport(), should I be usingpfree() to release the storage before the ereport()? Consider this example in C: PG_FUNCTION_INFO_V1(Example); Datum Example(PG_FUNCTION_ARGS) { VarChar* pstring=PG_GETARG_VARCHAR_P(0); VarChar* ret=NULL; int len = VARSIZE(pstring) - VARHDRSZ; char *string=palloc(len+1); memcpy(string, VARDATA(pstring), len); string[len] = '\0'; /* ... */ if ( /* some bad condition */ ) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("some bad condition occurred!"))); } /* ... */ pfree(string); if (ret == NULL) PG_RETURN_NULL(); else PG_RETURN_VARCHAR_P(ret); } I only have the pfree() at the end before the return if there is no error. If I fail to call pfree() before ereport(), doI have a memory leak?
On 1/6/2014 10:00 AM, Pfuntner, John wrote: > If I've done a palloc() to get storage inside a user-defined function and raise an error using ereport(), should I beusing pfree() to release the storage before the ereport()? > > Consider this example in C: > > PG_FUNCTION_INFO_V1(Example); > Datum > Example(PG_FUNCTION_ARGS) { > VarChar* pstring=PG_GETARG_VARCHAR_P(0); > VarChar* ret=NULL; > > int len = VARSIZE(pstring) - VARHDRSZ; > char *string=palloc(len+1); > memcpy(string, VARDATA(pstring), len); > string[len] = '\0'; > > /* ... */ > > if ( /* some bad condition */ ) { > ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("some bad condition occurred!"))); > } > > /* ... */ > > pfree(string); > > if (ret == NULL) > PG_RETURN_NULL(); > else > PG_RETURN_VARCHAR_P(ret); > } > > I only have the pfree() at the end before the return if there is no error. If I fail to call pfree() before ereport(),do I have a memory leak? No, this is why it is important to use palloc and malloc. -Steve
On Tue, Jan 7, 2014 at 12:46 AM, Stephen Woodbridge <woodbri@swoodbridge.com> wrote: > On 1/6/2014 10:00 AM, Pfuntner, John wrote: >> >> If I've done a palloc() to get storage inside a user-defined function and >> raise an error using ereport(), should I be using pfree() to release the >> storage before the ereport()? >> >> Consider this example in C: >> >> PG_FUNCTION_INFO_V1(Example); >> Datum >> Example(PG_FUNCTION_ARGS) { >> VarChar* pstring=PG_GETARG_VARCHAR_P(0); >> VarChar* ret=NULL; >> >> int len = VARSIZE(pstring) - VARHDRSZ; >> char *string=palloc(len+1); >> memcpy(string, VARDATA(pstring), len); >> string[len] = '\0'; >> >> /* ... */ >> >> if ( /* some bad condition */ ) { >> ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("some bad >> condition occurred!"))); >> } >> >> /* ... */ >> >> pfree(string); >> >> if (ret == NULL) >> PG_RETURN_NULL(); >> else >> PG_RETURN_VARCHAR_P(ret); >> } >> >> I only have the pfree() at the end before the return if there is no error. >> If I fail to call pfree() before ereport(), do I have a memory leak? > > > No, this is why it is important to use palloc and malloc. palloc allocates memory in the context of a transaction, meaning that it will be automatically freed when transaction finishes by either a commit or an abort. When calling ereport the transaction will be automatically aborted, hence free'ing the memory. Have a look here for more details: http://www.postgresql.org/docs/devel/static/xfunc-c.html#AEN54284 Regards, -- Michael