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

Examples:

-   result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult));
+   result = palloc_obj(IndexBuildResult);

-   collector->tuples = (IndexTuple *) palloc(sizeof(IndexTuple) *
                                              collector->lentuples);
+   collector->tuples = palloc_array(IndexTuple, collector->lentuples);

One common point is that the new interfaces all have a return type that automatically matches what they are allocating, so you don't need any casts nor have to manually make sure the size matches the expected result. Besides the additional safety, the notation is also more compact, as you can see above.

Inspired by the talloc library.

The interesting changes are in fe_memutils.h and palloc.h. The rest of the patch is just randomly sprinkled examples to test/validate the new additions.
From 9ba5753228e0fe9c1eca779e92795a29b23146af Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 17 May 2022 13:28:58 +0200
Subject: [PATCH] Expand palloc/pg_malloc API

This adds additional variants of palloc, pg_malloc, etc. that
encapsulate common usage patterns and provide more type safety.
Inspired by talloc library.
---
 src/include/common/fe_memutils.h | 46 ++++++++++++++++++++++++++
 src/include/utils/palloc.h       | 33 ++++++++++++++++++
 src/backend/access/brin/brin.c   | 14 ++++----
 src/backend/access/gin/ginfast.c | 17 ++++------
 src/backend/commands/indexcmds.c | 44 ++++++++++++------------
 src/backend/executor/nodeHash.c  | 57 +++++++++++++-------------------
 src/bin/pg_dump/common.c         | 24 +++++---------
 src/bin/pg_dump/pg_backup_tar.c  | 10 +++---
 src/bin/psql/startup.c           |  6 ++--
 src/common/config_info.c         |  2 +-
 src/common/controldata_utils.c   |  2 +-
 contrib/dblink/dblink.c          | 12 +++----
 12 files changed, 163 insertions(+), 104 deletions(-)

diff --git a/src/include/common/fe_memutils.h b/src/include/common/fe_memutils.h
index 0a4c9126ea..993e0b07cd 100644
--- a/src/include/common/fe_memutils.h
+++ b/src/include/common/fe_memutils.h
@@ -29,6 +29,39 @@ 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_obj(type) ((type *) pg_malloc(sizeof(type)))
+#define pg_malloc0_obj(type) ((type *) pg_malloc0(sizeof(type)))
+
+/*
+ * Allocate space for one object of what "ptr" points to
+ */
+#ifdef HAVE_TYPEOF
+#define pg_malloc_ptrtype(ptr) ((typeof(ptr)) pg_malloc(sizeof(*(ptr))))
+#define pg_malloc0_ptrtype(ptr) ((typeof(ptr)) pg_malloc0(sizeof(*(ptr))))
+#else
+#define pg_malloc_ptrtype(ptr) pg_malloc(sizeof(*(ptr)))
+#define pg_malloc0_ptrtype(ptr) pg_malloc0(sizeof(*(ptr)))
+#endif
+
+/*
+ * 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 +71,19 @@ extern void *palloc_extended(Size size, int flags);
 extern void *repalloc(void *pointer, Size size);
 extern void pfree(void *pointer);
 
+#define palloc_obj(type) ((type *) palloc(sizeof(type)))
+#define palloc0_obj(type) ((type *) palloc0(sizeof(type)))
+#ifdef HAVE_TYPEOF
+#define palloc_ptrtype(ptr) ((typeof(ptr)) palloc(sizeof(*(ptr))))
+#define palloc0_ptrtype(ptr) ((typeof(ptr)) palloc0(sizeof(*(ptr))))
+#else
+#define palloc_ptrtype(ptr) palloc(sizeof(*(ptr)))
+#define palloc0_ptrtype(ptr) palloc0(sizeof(*(ptr)))
+#endif
+#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);
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 332575f518..cbc9c11ffa 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -80,6 +80,39 @@ 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_obj(type) ((type *) palloc(sizeof(type)))
+#define palloc0_obj(type) ((type *) palloc0(sizeof(type)))
+
+/*
+ * Allocate space for one object of what "ptr" points to
+ */
+#ifdef HAVE_TYPEOF
+#define palloc_ptrtype(ptr) ((typeof(ptr)) palloc(sizeof(*(ptr))))
+#define palloc0_ptrtype(ptr) ((typeof(ptr)) palloc0(sizeof(*(ptr))))
+#else
+#define palloc_ptrtype(ptr) palloc(sizeof(*(ptr)))
+#define palloc0_ptrtype(ptr) palloc0(sizeof(*(ptr)))
+#endif
+
+/*
+ * 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.
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 52f171772d..e759bd54fa 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -330,7 +330,7 @@ brinbeginscan(Relation r, int nkeys, int norderbys)
 
        scan = RelationGetIndexScan(r, nkeys, norderbys);
 
-       opaque = (BrinOpaque *) palloc(sizeof(BrinOpaque));
+       opaque = palloc_obj(BrinOpaque);
        opaque->bo_rmAccess = brinRevmapInitialize(r, &opaque->bo_pagesPerRange,
                                                                                
           scan->xs_snapshot);
        opaque->bo_bdesc = brin_build_desc(r);
@@ -396,7 +396,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
         * don't look them up here; we do that lazily the first time we see a 
scan
         * key reference each of them.  We rely on zeroing fn_oid to InvalidOid.
         */
-       consistentFn = palloc0(sizeof(FmgrInfo) * bdesc->bd_tupdesc->natts);
+       consistentFn = palloc0_array(FmgrInfo, bdesc->bd_tupdesc->natts);
 
        /*
         * Make room for per-attribute lists of scan keys that we'll pass to the
@@ -883,7 +883,7 @@ brinbuild(Relation heap, Relation index, IndexInfo 
*indexInfo)
        /*
         * Return statistics
         */
-       result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult));
+       result = palloc_obj(IndexBuildResult);
 
        result->heap_tuples = reltuples;
        result->index_tuples = idxtuples;
@@ -927,7 +927,7 @@ brinbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult 
*stats,
 {
        /* allocate stats if first time through, else re-use existing struct */
        if (stats == NULL)
-               stats = (IndexBulkDeleteResult *) 
palloc0(sizeof(IndexBulkDeleteResult));
+               stats = palloc0_obj(IndexBulkDeleteResult);
 
        return stats;
 }
@@ -946,7 +946,7 @@ brinvacuumcleanup(IndexVacuumInfo *info, 
IndexBulkDeleteResult *stats)
                return stats;
 
        if (!stats)
-               stats = (IndexBulkDeleteResult *) 
palloc0(sizeof(IndexBulkDeleteResult));
+               stats = palloc0_obj(IndexBulkDeleteResult);
        stats->num_pages = RelationGetNumberOfBlocks(info->index);
        /* rest of stats is initialized by zeroing */
 
@@ -1200,7 +1200,7 @@ brin_build_desc(Relation rel)
         * Obtain BrinOpcInfo for each indexed column.  While at it, accumulate
         * the number of columns stored, since the number is opclass-defined.
         */
-       opcinfo = (BrinOpcInfo **) palloc(sizeof(BrinOpcInfo *) * 
tupdesc->natts);
+       opcinfo = palloc_array(BrinOpcInfo*, tupdesc->natts);
        for (keyno = 0; keyno < tupdesc->natts; keyno++)
        {
                FmgrInfo   *opcInfoFn;
@@ -1272,7 +1272,7 @@ initialize_brin_buildstate(Relation idxRel, BrinRevmap 
*revmap,
 {
        BrinBuildState *state;
 
-       state = palloc(sizeof(BrinBuildState));
+       state = palloc_obj(BrinBuildState);
 
        state->bs_irel = idxRel;
        state->bs_numtuples = 0;
diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c
index 7409fdc165..2999c94e2b 100644
--- a/src/backend/access/gin/ginfast.c
+++ b/src/backend/access/gin/ginfast.c
@@ -505,7 +505,7 @@ ginHeapTupleFastCollect(GinState *ginstate,
                 * resizing (since palloc likes powers of 2).
                 */
                collector->lentuples = pg_nextpower2_32(Max(16, nentries));
-               collector->tuples = (IndexTuple *) palloc(sizeof(IndexTuple) * 
collector->lentuples);
+               collector->tuples = palloc_array(IndexTuple, 
collector->lentuples);
        }
        else if (collector->lentuples < collector->ntuples + nentries)
        {
@@ -515,8 +515,8 @@ ginHeapTupleFastCollect(GinState *ginstate,
                 * MaxAllocSize/sizeof(IndexTuple), causing an error in 
repalloc.
                 */
                collector->lentuples = pg_nextpower2_32(collector->ntuples + 
nentries);
-               collector->tuples = (IndexTuple *) repalloc(collector->tuples,
-                                                                               
                        sizeof(IndexTuple) * collector->lentuples);
+               collector->tuples = repalloc_array(collector->tuples,
+                                                                               
   IndexTuple, collector->lentuples);
        }
 
        /*
@@ -665,9 +665,8 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber 
newHead,
 static void
 initKeyArray(KeyArray *keys, int32 maxvalues)
 {
-       keys->keys = (Datum *) palloc(sizeof(Datum) * maxvalues);
-       keys->categories = (GinNullCategory *)
-               palloc(sizeof(GinNullCategory) * maxvalues);
+       keys->keys = palloc_array(Datum, maxvalues);
+       keys->categories = palloc_array(GinNullCategory, maxvalues);
        keys->nvalues = 0;
        keys->maxvalues = maxvalues;
 }
@@ -679,10 +678,8 @@ addDatum(KeyArray *keys, Datum datum, GinNullCategory 
category)
        if (keys->nvalues >= keys->maxvalues)
        {
                keys->maxvalues *= 2;
-               keys->keys = (Datum *)
-                       repalloc(keys->keys, sizeof(Datum) * keys->maxvalues);
-               keys->categories = (GinNullCategory *)
-                       repalloc(keys->categories, sizeof(GinNullCategory) * 
keys->maxvalues);
+               keys->keys = repalloc_array(keys->keys, Datum, keys->maxvalues);
+               keys->categories = repalloc_array(keys->categories, 
GinNullCategory, keys->maxvalues);
        }
 
        keys->keys[keys->nvalues] = datum;
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index eac13ac0b7..25bd691ee0 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -227,10 +227,10 @@ CheckIndexCompatible(Oid oldId,
         */
        indexInfo = makeIndexInfo(numberOfAttributes, numberOfAttributes,
                                                          accessMethodId, NIL, 
NIL, false, false, false, false);
-       typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-       collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-       classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-       coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
+       typeObjectId = palloc_array(Oid, numberOfAttributes);
+       collationObjectId = palloc_array(Oid, numberOfAttributes);
+       classObjectId = palloc_array(Oid, numberOfAttributes);
+       coloptions = palloc_array(int16, numberOfAttributes);
        ComputeIndexAttrs(indexInfo,
                                          typeObjectId, collationObjectId, 
classObjectId,
                                          coloptions, attributeList,
@@ -881,10 +881,10 @@ DefineIndex(Oid relationId,
                                                          !concurrent,
                                                          concurrent);
 
-       typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-       collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-       classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-       coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
+       typeObjectId = palloc_array(Oid, numberOfAttributes);
+       collationObjectId = palloc_array(Oid, numberOfAttributes);
+       classObjectId = palloc_array(Oid, numberOfAttributes);
+       coloptions = palloc_array(int16, numberOfAttributes);
        ComputeIndexAttrs(indexInfo,
                                          typeObjectId, collationObjectId, 
classObjectId,
                                          coloptions, allIndexParams,
@@ -1198,7 +1198,7 @@ DefineIndex(Oid relationId,
                if ((!stmt->relation || stmt->relation->inh) && 
partdesc->nparts > 0)
                {
                        int                     nparts = partdesc->nparts;
-                       Oid                *part_oids = palloc(sizeof(Oid) * 
nparts);
+                       Oid                *part_oids = palloc_array(Oid, 
nparts);
                        bool            invalidate_parent = false;
                        TupleDesc       parentDesc;
                        Oid                *opfamOids;
@@ -1209,7 +1209,7 @@ DefineIndex(Oid relationId,
                        memcpy(part_oids, partdesc->oids, sizeof(Oid) * nparts);
 
                        parentDesc = RelationGetDescr(rel);
-                       opfamOids = palloc(sizeof(Oid) * numberOfKeyAttributes);
+                       opfamOids = palloc_array(Oid, numberOfKeyAttributes);
                        for (i = 0; i < numberOfKeyAttributes; i++)
                                opfamOids[i] = 
get_opclass_family(classObjectId[i]);
 
@@ -1754,9 +1754,9 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
        if (exclusionOpNames)
        {
                Assert(list_length(exclusionOpNames) == nkeycols);
-               indexInfo->ii_ExclusionOps = (Oid *) palloc(sizeof(Oid) * 
nkeycols);
-               indexInfo->ii_ExclusionProcs = (Oid *) palloc(sizeof(Oid) * 
nkeycols);
-               indexInfo->ii_ExclusionStrats = (uint16 *) 
palloc(sizeof(uint16) * nkeycols);
+               indexInfo->ii_ExclusionOps = palloc_array(Oid, nkeycols);
+               indexInfo->ii_ExclusionProcs = palloc_array(Oid, nkeycols);
+               indexInfo->ii_ExclusionStrats = palloc_array(uint16, nkeycols);
                nextExclOp = list_head(exclusionOpNames);
        }
        else
@@ -2036,7 +2036,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
 
                        if (!indexInfo->ii_OpclassOptions)
                                indexInfo->ii_OpclassOptions =
-                                       palloc0(sizeof(Datum) * 
indexInfo->ii_NumIndexAttrs);
+                                       palloc0_array(Datum, 
indexInfo->ii_NumIndexAttrs);
 
                        indexInfo->ii_OpclassOptions[attn] =
                                transformRelOptions((Datum) 0, 
attribute->opclassopts,
@@ -3372,7 +3372,7 @@ ReindexRelationConcurrently(Oid relationOid, 
ReindexParams *params)
                                                /* Save the list of relation 
OIDs in private context */
                                                oldcontext = 
MemoryContextSwitchTo(private_context);
 
-                                               idx = 
palloc(sizeof(ReindexIndexInfo));
+                                               idx = 
palloc_obj(ReindexIndexInfo);
                                                idx->indexId = cellOid;
                                                /* other fields set later */
 
@@ -3421,7 +3421,7 @@ ReindexRelationConcurrently(Oid relationOid, 
ReindexParams *params)
                                                         */
                                                        oldcontext = 
MemoryContextSwitchTo(private_context);
 
-                                                       idx = 
palloc(sizeof(ReindexIndexInfo));
+                                                       idx = 
palloc_obj(ReindexIndexInfo);
                                                        idx->indexId = cellOid;
                                                        indexIds = 
lappend(indexIds, idx);
                                                        /* other fields set 
later */
@@ -3502,7 +3502,7 @@ ReindexRelationConcurrently(Oid relationOid, 
ReindexParams *params)
                                 * Save the list of relation OIDs in private 
context.  Note
                                 * that invalid indexes are allowed here.
                                 */
-                               idx = palloc(sizeof(ReindexIndexInfo));
+                               idx = palloc_obj(ReindexIndexInfo);
                                idx->indexId = relationOid;
                                indexIds = lappend(indexIds, idx);
                                /* other fields set later */
@@ -3647,7 +3647,7 @@ ReindexRelationConcurrently(Oid relationOid, 
ReindexParams *params)
                 */
                oldcontext = MemoryContextSwitchTo(private_context);
 
-               newidx = palloc(sizeof(ReindexIndexInfo));
+               newidx = palloc_obj(ReindexIndexInfo);
                newidx->indexId = newIndexId;
                newidx->safe = idx->safe;
                newidx->tableId = idx->tableId;
@@ -3661,10 +3661,10 @@ ReindexRelationConcurrently(Oid relationOid, 
ReindexParams *params)
                 * avoid multiple locks taken on the same relation, instead we 
rely on
                 * parentRelationIds built earlier.
                 */
-               lockrelid = palloc(sizeof(*lockrelid));
+               lockrelid = palloc_ptrtype(lockrelid);
                *lockrelid = indexRel->rd_lockInfo.lockRelId;
                relationLocks = lappend(relationLocks, lockrelid);
-               lockrelid = palloc(sizeof(*lockrelid));
+               lockrelid = palloc_ptrtype(lockrelid);
                *lockrelid = newIndexRel->rd_lockInfo.lockRelId;
                relationLocks = lappend(relationLocks, lockrelid);
 
@@ -3696,11 +3696,11 @@ ReindexRelationConcurrently(Oid relationOid, 
ReindexParams *params)
                oldcontext = MemoryContextSwitchTo(private_context);
 
                /* Add lockrelid of heap relation to the list of locked 
relations */
-               lockrelid = palloc(sizeof(*lockrelid));
+               lockrelid = palloc_ptrtype(lockrelid);
                *lockrelid = heapRelation->rd_lockInfo.lockRelId;
                relationLocks = lappend(relationLocks, lockrelid);
 
-               heaplocktag = (LOCKTAG *) palloc(sizeof(LOCKTAG));
+               heaplocktag = palloc_obj(LOCKTAG);
 
                /* Save the LOCKTAG for this parent relation for the wait phase 
*/
                SET_LOCKTAG_RELATION(*heaplocktag, lockrelid->dbId, 
lockrelid->relId);
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 3510a4247c..0535161dc1 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -479,7 +479,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, 
List *hashCollations,
         * per-query memory context.  Everything else should be kept inside the
         * subsidiary hashCxt or batchCxt.
         */
-       hashtable = (HashJoinTable) palloc(sizeof(HashJoinTableData));
+       hashtable = palloc_obj(HashJoinTableData);
        hashtable->nbuckets = nbuckets;
        hashtable->nbuckets_original = nbuckets;
        hashtable->nbuckets_optimal = nbuckets;
@@ -540,12 +540,10 @@ ExecHashTableCreate(HashState *state, List 
*hashOperators, List *hashCollations,
         * remember whether the join operators are strict.
         */
        nkeys = list_length(hashOperators);
-       hashtable->outer_hashfunctions =
-               (FmgrInfo *) palloc(nkeys * sizeof(FmgrInfo));
-       hashtable->inner_hashfunctions =
-               (FmgrInfo *) palloc(nkeys * sizeof(FmgrInfo));
-       hashtable->hashStrict = (bool *) palloc(nkeys * sizeof(bool));
-       hashtable->collations = (Oid *) palloc(nkeys * sizeof(Oid));
+       hashtable->outer_hashfunctions = palloc_array(FmgrInfo, nkeys);
+       hashtable->inner_hashfunctions = palloc_array(FmgrInfo, nkeys);
+       hashtable->hashStrict = palloc_array(bool, nkeys);
+       hashtable->collations = palloc_array(Oid, nkeys);
        i = 0;
        forboth(ho, hashOperators, hc, hashCollations)
        {
@@ -569,10 +567,8 @@ ExecHashTableCreate(HashState *state, List *hashOperators, 
List *hashCollations,
                 * allocate and initialize the file arrays in hashCxt (not 
needed for
                 * parallel case which uses shared tuplestores instead of raw 
files)
                 */
-               hashtable->innerBatchFile = (BufFile **)
-                       palloc0(nbatch * sizeof(BufFile *));
-               hashtable->outerBatchFile = (BufFile **)
-                       palloc0(nbatch * sizeof(BufFile *));
+               hashtable->innerBatchFile = palloc0_array(BufFile *, nbatch);
+               hashtable->outerBatchFile = palloc0_array(BufFile *, nbatch);
                /* The files will not be opened until needed... */
                /* ... but make sure we have temp tablespaces established for 
them */
                PrepareTempTablespaces();
@@ -636,8 +632,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, 
List *hashCollations,
                 */
                MemoryContextSwitchTo(hashtable->batchCxt);
 
-               hashtable->buckets.unshared = (HashJoinTuple *)
-                       palloc0(nbuckets * sizeof(HashJoinTuple));
+               hashtable->buckets.unshared = palloc0_array(HashJoinTuple, 
nbuckets);
 
                /*
                 * Set up for skew optimization, if possible and there's a need 
for
@@ -934,20 +929,16 @@ ExecHashIncreaseNumBatches(HashJoinTable hashtable)
        if (hashtable->innerBatchFile == NULL)
        {
                /* we had no file arrays before */
-               hashtable->innerBatchFile = (BufFile **)
-                       palloc0(nbatch * sizeof(BufFile *));
-               hashtable->outerBatchFile = (BufFile **)
-                       palloc0(nbatch * sizeof(BufFile *));
+               hashtable->innerBatchFile = palloc0_array(BufFile *, nbatch);
+               hashtable->outerBatchFile = palloc0_array(BufFile *, nbatch);
                /* time to establish the temp tablespaces, too */
                PrepareTempTablespaces();
        }
        else
        {
                /* enlarge arrays and zero out added entries */
-               hashtable->innerBatchFile = (BufFile **)
-                       repalloc(hashtable->innerBatchFile, nbatch * 
sizeof(BufFile *));
-               hashtable->outerBatchFile = (BufFile **)
-                       repalloc(hashtable->outerBatchFile, nbatch * 
sizeof(BufFile *));
+               hashtable->innerBatchFile = 
repalloc_array(hashtable->innerBatchFile, BufFile *, nbatch);
+               hashtable->outerBatchFile = 
repalloc_array(hashtable->outerBatchFile, BufFile *, nbatch);
                MemSet(hashtable->innerBatchFile + oldnbatch, 0,
                           (nbatch - oldnbatch) * sizeof(BufFile *));
                MemSet(hashtable->outerBatchFile + oldnbatch, 0,
@@ -974,8 +965,8 @@ ExecHashIncreaseNumBatches(HashJoinTable hashtable)
                hashtable->log2_nbuckets = hashtable->log2_nbuckets_optimal;
 
                hashtable->buckets.unshared =
-                       repalloc(hashtable->buckets.unshared,
-                                        sizeof(HashJoinTuple) * 
hashtable->nbuckets);
+                       repalloc_array(hashtable->buckets.unshared,
+                                                  HashJoinTuple, 
hashtable->nbuckets);
        }
 
        /*
@@ -1369,7 +1360,7 @@ ExecParallelHashRepartitionRest(HashJoinTable hashtable)
        /* Get our hands on the previous generation of batches. */
        old_batches = (ParallelHashJoinBatch *)
                dsa_get_address(hashtable->area, pstate->old_batches);
-       old_inner_tuples = palloc0(sizeof(SharedTuplestoreAccessor *) * 
old_nbatch);
+       old_inner_tuples = palloc0_array(SharedTuplestoreAccessor *, 
old_nbatch);
        for (i = 1; i < old_nbatch; ++i)
        {
                ParallelHashJoinBatch *shared =
@@ -1475,8 +1466,8 @@ ExecHashIncreaseNumBuckets(HashJoinTable hashtable)
         * chunks)
         */
        hashtable->buckets.unshared =
-               (HashJoinTuple *) repalloc(hashtable->buckets.unshared,
-                                                                  
hashtable->nbuckets * sizeof(HashJoinTuple));
+               repalloc_array(hashtable->buckets.unshared,
+                                          HashJoinTuple, hashtable->nbuckets);
 
        memset(hashtable->buckets.unshared, 0,
                   hashtable->nbuckets * sizeof(HashJoinTuple));
@@ -2168,8 +2159,7 @@ ExecHashTableReset(HashJoinTable hashtable)
        oldcxt = MemoryContextSwitchTo(hashtable->batchCxt);
 
        /* Reallocate and reinitialize the hash bucket headers. */
-       hashtable->buckets.unshared = (HashJoinTuple *)
-               palloc0(nbuckets * sizeof(HashJoinTuple));
+       hashtable->buckets.unshared = palloc0_array(HashJoinTuple, nbuckets);
 
        hashtable->spaceUsed = 0;
 
@@ -2662,8 +2652,7 @@ ExecShutdownHash(HashState *node)
 {
        /* Allocate save space if EXPLAIN'ing and we didn't do so already */
        if (node->ps.instrument && !node->hinstrument)
-               node->hinstrument = (HashInstrumentation *)
-                       palloc0(sizeof(HashInstrumentation));
+               node->hinstrument = palloc0_obj(HashInstrumentation);
        /* Now accumulate data for the current (final) hash table */
        if (node->hinstrument && node->hashtable)
                ExecHashAccumInstrumentation(node->hinstrument, 
node->hashtable);
@@ -2973,8 +2962,8 @@ ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, 
int nbatch)
 
        /* Allocate this backend's accessor array. */
        hashtable->nbatch = nbatch;
-       hashtable->batches = (ParallelHashJoinBatchAccessor *)
-               palloc0(sizeof(ParallelHashJoinBatchAccessor) * 
hashtable->nbatch);
+       hashtable->batches =
+               palloc0_array(ParallelHashJoinBatchAccessor, hashtable->nbatch);
 
        /* Set up the shared state, tuplestores and backend-local accessors. */
        for (i = 0; i < hashtable->nbatch; ++i)
@@ -3079,8 +3068,8 @@ ExecParallelHashEnsureBatchAccessors(HashJoinTable 
hashtable)
 
        /* Allocate this backend's accessor array. */
        hashtable->nbatch = pstate->nbatch;
-       hashtable->batches = (ParallelHashJoinBatchAccessor *)
-               palloc0(sizeof(ParallelHashJoinBatchAccessor) * 
hashtable->nbatch);
+       hashtable->batches =
+               palloc0_array(ParallelHashJoinBatchAccessor, hashtable->nbatch);
 
        /* Find the base of the pseudo-array of ParallelHashJoinBatch objects. 
*/
        batches = (ParallelHashJoinBatch *)
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 794e6e7ce9..c799dc4300 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -400,7 +400,7 @@ flagInhIndexes(Archive *fout, TableInfo tblinfo[], int 
numTables)
                        if (parentidx == NULL)
                                continue;
 
-                       attachinfo = (IndexAttachInfo *) 
pg_malloc(sizeof(IndexAttachInfo));
+                       attachinfo = pg_malloc_obj(IndexAttachInfo);
 
                        attachinfo->dobj.objType = DO_INDEX_ATTACH;
                        attachinfo->dobj.catId.tableoid = 0;
@@ -530,7 +530,7 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int 
numTables)
                        {
                                AttrDefInfo *attrDef;
 
-                               attrDef = (AttrDefInfo *) 
pg_malloc(sizeof(AttrDefInfo));
+                               attrDef = pg_malloc_obj(AttrDefInfo);
                                attrDef->dobj.objType = DO_ATTRDEF;
                                attrDef->dobj.catId.tableoid = 0;
                                attrDef->dobj.catId.oid = 0;
@@ -600,14 +600,12 @@ AssignDumpId(DumpableObject *dobj)
                if (allocedDumpIds <= 0)
                {
                        newAlloc = 256;
-                       dumpIdMap = (DumpableObject **)
-                               pg_malloc(newAlloc * sizeof(DumpableObject *));
+                       dumpIdMap = pg_malloc_array(DumpableObject *, newAlloc);
                }
                else
                {
                        newAlloc = allocedDumpIds * 2;
-                       dumpIdMap = (DumpableObject **)
-                               pg_realloc(dumpIdMap, newAlloc * 
sizeof(DumpableObject *));
+                       dumpIdMap = pg_realloc_array(dumpIdMap, DumpableObject 
*, newAlloc);
                }
                memset(dumpIdMap + allocedDumpIds, 0,
                           (newAlloc - allocedDumpIds) * sizeof(DumpableObject 
*));
@@ -700,8 +698,7 @@ getDumpableObjects(DumpableObject ***objs, int *numObjs)
        int                     i,
                                j;
 
-       *objs = (DumpableObject **)
-               pg_malloc(allocedDumpIds * sizeof(DumpableObject *));
+       *objs = pg_malloc_array(DumpableObject *, allocedDumpIds);
        j = 0;
        for (i = 1; i < allocedDumpIds; i++)
        {
@@ -724,15 +721,13 @@ addObjectDependency(DumpableObject *dobj, DumpId refId)
                if (dobj->allocDeps <= 0)
                {
                        dobj->allocDeps = 16;
-                       dobj->dependencies = (DumpId *)
-                               pg_malloc(dobj->allocDeps * sizeof(DumpId));
+                       dobj->dependencies = pg_malloc_array(DumpId, 
dobj->allocDeps);
                }
                else
                {
                        dobj->allocDeps *= 2;
-                       dobj->dependencies = (DumpId *)
-                               pg_realloc(dobj->dependencies,
-                                                  dobj->allocDeps * 
sizeof(DumpId));
+                       dobj->dependencies = 
pg_realloc_array(dobj->dependencies,
+                                                                               
                  DumpId, dobj->allocDeps);
                }
        }
        dobj->dependencies[dobj->nDeps++] = refId;
@@ -990,8 +985,7 @@ findParentsByOid(TableInfo *self,
 
        if (numParents > 0)
        {
-               self->parents = (TableInfo **)
-                       pg_malloc(sizeof(TableInfo *) * numParents);
+               self->parents = pg_malloc_array(TableInfo *, numParents);
                j = 0;
                for (i = 0; i < numInherits; i++)
                {
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 39d71badb7..2443d99e69 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -151,7 +151,7 @@ InitArchiveFmt_Tar(ArchiveHandle *AH)
        /*
         * Set up some special context used in compressing data.
         */
-       ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
+       ctx = pg_malloc0_obj(lclContext);
        AH->formatData = (void *) ctx;
        ctx->filePos = 0;
        ctx->isSpecialScript = 0;
@@ -240,7 +240,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
        lclTocEntry *ctx;
        char            fn[K_STD_BUF_SIZE];
 
-       ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
+       ctx = pg_malloc0_obj(lclTocEntry);
        if (te->dataDumper != NULL)
        {
                snprintf(fn, sizeof(fn), "%d.dat", te->dumpId);
@@ -272,7 +272,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
 
        if (ctx == NULL)
        {
-               ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
+               ctx = pg_malloc0_obj(lclTocEntry);
                te->formatData = (void *) ctx;
        }
 
@@ -337,7 +337,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
        {
                int                     old_umask;
 
-               tm = pg_malloc0(sizeof(TAR_MEMBER));
+               tm = pg_malloc0_obj(TAR_MEMBER);
 
                /*
                 * POSIX does not require, but permits, tmpfile() to restrict 
file
@@ -1053,7 +1053,7 @@ static TAR_MEMBER *
 _tarPositionTo(ArchiveHandle *AH, const char *filename)
 {
        lclContext *ctx = (lclContext *) AH->formatData;
-       TAR_MEMBER *th = pg_malloc0(sizeof(TAR_MEMBER));
+       TAR_MEMBER *th = pg_malloc0_obj(TAR_MEMBER);
        char            c;
        char            header[TAR_BLOCK_SIZE];
        size_t          i,
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index ddff903915..807be8bb19 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -247,8 +247,8 @@ main(int argc, char *argv[])
        do
        {
 #define PARAMS_ARRAY_SIZE      8
-               const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * 
sizeof(*keywords));
-               const char **values = pg_malloc(PARAMS_ARRAY_SIZE * 
sizeof(*values));
+               const char **keywords = pg_malloc_array(const char *, 
PARAMS_ARRAY_SIZE);
+               const char **values = pg_malloc_array(const char *, 
PARAMS_ARRAY_SIZE);
 
                keywords[0] = "host";
                values[0] = options.host;
@@ -743,7 +743,7 @@ simple_action_list_append(SimpleActionList *list,
 {
        SimpleActionListCell *cell;
 
-       cell = (SimpleActionListCell *) pg_malloc(sizeof(SimpleActionListCell));
+       cell = pg_malloc_obj(SimpleActionListCell);
 
        cell->next = NULL;
        cell->action = action;
diff --git a/src/common/config_info.c b/src/common/config_info.c
index aa643b63fe..891a1505cc 100644
--- a/src/common/config_info.c
+++ b/src/common/config_info.c
@@ -39,7 +39,7 @@ get_configdata(const char *my_exec_path, size_t 
*configdata_len)
 
        /* Adjust this to match the number of items filled below */
        *configdata_len = 23;
-       configdata = (ConfigData *) palloc(*configdata_len * 
sizeof(ConfigData));
+       configdata = palloc_array(ConfigData, *configdata_len);
 
        configdata[i].name = pstrdup("BINDIR");
        strlcpy(path, my_exec_path, sizeof(path));
diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c
index 4c0da6e124..d1cb819842 100644
--- a/src/common/controldata_utils.c
+++ b/src/common/controldata_utils.c
@@ -59,7 +59,7 @@ get_controlfile(const char *DataDir, bool *crc_ok_p)
 
        AssertArg(crc_ok_p);
 
-       ControlFile = palloc(sizeof(ControlFileData));
+       ControlFile = palloc_obj(ControlFileData);
        snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
 
 #ifndef FRONTEND
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index a561d1d652..9c5b9c4c26 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -973,7 +973,7 @@ materializeResult(FunctionCallInfo fcinfo, PGconn *conn, 
PGresult *res)
                        rsinfo->setDesc = tupdesc;
                        MemoryContextSwitchTo(oldcontext);
 
-                       values = (char **) palloc(nfields * sizeof(char *));
+                       values = palloc_array(char *, nfields);
 
                        /* put all tuples into the tuplestore */
                        for (row = 0; row < ntuples; row++)
@@ -1277,7 +1277,7 @@ storeRow(volatile storeInfo *sinfo, PGresult *res, bool 
first)
                 */
                if (sinfo->cstrs)
                        pfree(sinfo->cstrs);
-               sinfo->cstrs = (char **) palloc(nfields * sizeof(char *));
+               sinfo->cstrs = palloc_array(char *, nfields);
        }
 
        /* Should have a single-row result if we get here */
@@ -1619,7 +1619,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
                HeapTuple       tuple;
                Datum           result;
 
-               values = (char **) palloc(2 * sizeof(char *));
+               values = palloc_array(char *, 2);
                values[0] = psprintf("%d", call_cntr + 1);
                values[1] = results[call_cntr];
 
@@ -2084,7 +2084,7 @@ get_pkey_attnames(Relation rel, int16 *indnkeyatts)
                        *indnkeyatts = index->indnkeyatts;
                        if (*indnkeyatts > 0)
                        {
-                               result = (char **) palloc(*indnkeyatts * 
sizeof(char *));
+                               result = palloc_array(char *, *indnkeyatts);
 
                                for (i = 0; i < *indnkeyatts; i++)
                                        result[i] = SPI_fname(tupdesc, 
index->indkey.values[i]);
@@ -2125,7 +2125,7 @@ get_text_array_contents(ArrayType *array, int *numitems)
        get_typlenbyvalalign(ARR_ELEMTYPE(array),
                                                 &typlen, &typbyval, &typalign);
 
-       values = (char **) palloc(nitems * sizeof(char *));
+       values = palloc_array(char *, nitems);
 
        ptr = ARR_DATA_PTR(array);
        bitmap = ARR_NULLBITMAP(array);
@@ -2930,7 +2930,7 @@ validate_pkattnums(Relation rel,
                                 errmsg("number of key attributes must be > 
0")));
 
        /* Allocate output array */
-       *pkattnums = (int *) palloc(pknumatts_arg * sizeof(int));
+       *pkattnums = palloc_array(int, pknumatts_arg);
        *pknumatts = pknumatts_arg;
 
        /* Validate attnums and convert to internal form */
-- 
2.35.1

Reply via email to