Expand palloc/pg_malloc API for more type safety

This adds additional variants of palloc, pg_malloc, etc. that
encapsulate common usage patterns and provide more type safety.

Specifically, this adds palloc_object(), palloc_array(), and
repalloc_array(), which take the type name of the object to be
allocated as its first argument and cast the return as a pointer to
that type.  There are also palloc0_object() and palloc0_array()
variants for initializing with zero, and pg_malloc_*() variants of all
of the above.

Inspired by the talloc library.

This is backpatched from master so that future backpatchable code can
make use of these APIs.  This patch by itself does not contain any
users of these APIs.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/bb755632-2a43-d523-36f8-a1e7a389a907@enterprisedb.com
This commit is contained in:
Peter Eisentraut 2022-09-14 06:04:24 +02:00
parent c2aa5d01e3
commit b7f37af7c1
2 changed files with 50 additions and 0 deletions

View File

@ -29,6 +29,28 @@ extern void *pg_malloc_extended(size_t size, int flags);
extern void *pg_realloc(void *pointer, size_t size);
extern void pg_free(void *pointer);
/*
* Variants with easier notation and more type safety
*/
/*
* Allocate space for one object of type "type"
*/
#define pg_malloc_object(type) ((type *) pg_malloc(sizeof(type)))
#define pg_malloc0_object(type) ((type *) pg_malloc0(sizeof(type)))
/*
* Allocate space for "count" objects of type "type"
*/
#define pg_malloc_array(type, count) ((type *) pg_malloc(sizeof(type) * (count)))
#define pg_malloc0_array(type, count) ((type *) pg_malloc0(sizeof(type) * (count)))
/*
* Change size of allocation pointed to by "pointer" to have space for "count"
* objects of type "type"
*/
#define pg_realloc_array(pointer, type, count) ((type *) pg_realloc(pointer, sizeof(type) * (count)))
/* Equivalent functions, deliberately named the same as backend functions */
extern char *pstrdup(const char *in);
extern char *pnstrdup(const char *in, Size size);
@ -38,6 +60,12 @@ extern void *palloc_extended(Size size, int flags);
extern void *repalloc(void *pointer, Size size);
extern void pfree(void *pointer);
#define palloc_object(type) ((type *) palloc(sizeof(type)))
#define palloc0_object(type) ((type *) palloc0(sizeof(type)))
#define palloc_array(type, count) ((type *) palloc(sizeof(type) * (count)))
#define palloc0_array(type, count) ((type *) palloc0(sizeof(type) * (count)))
#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count)))
/* sprintf into a palloc'd buffer --- these are in psprintf.c */
extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2);
extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0);

View File

@ -80,6 +80,28 @@ extern void *palloc_extended(Size size, int flags);
extern pg_nodiscard void *repalloc(void *pointer, Size size);
extern void pfree(void *pointer);
/*
* Variants with easier notation and more type safety
*/
/*
* Allocate space for one object of type "type"
*/
#define palloc_object(type) ((type *) palloc(sizeof(type)))
#define palloc0_object(type) ((type *) palloc0(sizeof(type)))
/*
* Allocate space for "count" objects of type "type"
*/
#define palloc_array(type, count) ((type *) palloc(sizeof(type) * (count)))
#define palloc0_array(type, count) ((type *) palloc0(sizeof(type) * (count)))
/*
* Change size of allocation pointed to by "pointer" to have space for "count"
* objects of type "type"
*/
#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count)))
/*
* The result of palloc() is always word-aligned, so we can skip testing
* alignment of the pointer when deciding which MemSet variant to use.