]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
A macro for the size of a struct with a flexible array member
authorTony Finch <fanf@isc.org>
Thu, 9 Mar 2023 10:43:53 +0000 (10:43 +0000)
committerTony Finch <fanf@isc.org>
Fri, 12 May 2023 19:48:31 +0000 (20:48 +0100)
It can be fairly long-winded to allocate space for a struct with a
flexible array member: in general we need the size of the struct, the
size of the member, and the number of elements. Wrap them all up in a
STRUCT_FLEX_SIZE() macro, and use the new macro for the flexible
arrays in isc_ht and dns_qp.

lib/dns/qp.c
lib/isc/histo.c
lib/isc/ht.c
lib/isc/include/isc/util.h

index 60acf13ed520bac5076f15aaddad7ca13a21fb73..fec71033b1622dc4cdd8c1c8d4e2c1b565e9fbc1 100644 (file)
@@ -426,13 +426,13 @@ static void
 realloc_chunk_arrays(dns_qp_t *qp, qp_chunk_t newmax) {
        size_t oldptrs = sizeof(qp->base->ptr[0]) * qp->chunk_max;
        size_t newptrs = sizeof(qp->base->ptr[0]) * newmax;
-       size_t allbytes = sizeof(dns_qpbase_t) + newptrs;
+       size_t size = STRUCT_FLEX_SIZE(qp->base, ptr, newmax);
 
        if (qp->base == NULL || qpbase_unref(qp)) {
-               qp->base = isc_mem_reallocate(qp->mctx, qp->base, allbytes);
+               qp->base = isc_mem_reallocate(qp->mctx, qp->base, size);
        } else {
                dns_qpbase_t *oldbase = qp->base;
-               qp->base = isc_mem_allocate(qp->mctx, allbytes);
+               qp->base = isc_mem_allocate(qp->mctx, size);
                memmove(&qp->base->ptr[0], &oldbase->ptr[0], oldptrs);
        }
        memset(&qp->base->ptr[qp->chunk_max], 0, newptrs - oldptrs);
index 395b27b6b612de15f983ffb6be388aafe181af1e..870c3c0152f1eead2c3e3f4bb4c7a047a10d6b04 100644 (file)
 #include <isc/mem.h>
 #include <isc/tid.h>
 
-/*
- * XXXFANF to be added to <isc/util.h> by a commmit in a qp-trie
- * feature branch
- */
-#define STRUCT_FLEX_SIZE(pointer, member, count) \
-       (sizeof(*(pointer)) + sizeof(*(pointer)->member) * (count))
-
 /*
  * XXXFANF this should probably be in <isc/util.h> too
  */
index d9de112e54bed7ab742814196d84098f9305c221..4d771882dd7c2f7a59dc902c89079fb6c15dd2de 100644 (file)
@@ -287,7 +287,7 @@ isc__ht_add(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize,
 
        hash = hash_32(hashval, ht->hashbits[idx]);
 
-       node = isc_mem_get(ht->mctx, sizeof(*node) + keysize);
+       node = isc_mem_get(ht->mctx, STRUCT_FLEX_SIZE(node, key, keysize));
        *node = (isc_ht_node_t){
                .keysize = keysize,
                .hashval = hashval,
@@ -396,7 +396,7 @@ isc__ht_delete(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize,
                                prev->next = node->next;
                        }
                        isc_mem_put(ht->mctx, node,
-                                   sizeof(*node) + node->keysize);
+                                   STRUCT_FLEX_SIZE(node, key, node->keysize));
                        ht->count--;
 
                        return (ISC_R_SUCCESS);
index 7fe6715a4eb80231cc1f38c80c864b2c6e467004..c8b6e1c99f25199d79cb3c4ad5e666f6b9712a6b 100644 (file)
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 
+/*%
+ * Get the allocation size for a struct with a flexible array member
+ * containing `count` elements. The struct is identified by a pointer,
+ * typically the one that points to (or will point to) the allocation.
+ */
+#define STRUCT_FLEX_SIZE(pointer, member, count) \
+       (sizeof(*(pointer)) + sizeof(*(pointer)->member) * (count))
+
 /*%
  * Use this in translation units that would otherwise be empty, to
  * suppress compiler warnings.