David Allan wrote: > Allocates a buffer containing a struct with variable sized array as the last member, useful for some ioctl and other APIs that return data in this way. > --- > src/util/memory.h | 18 ++++++++++++++++++ > 1 files changed, 18 insertions(+), 0 deletions(-) > > diff --git a/src/util/memory.h b/src/util/memory.h > index fc9e6c1..e7effd6 100644 > --- a/src/util/memory.h > +++ b/src/util/memory.h > @@ -76,6 +76,24 @@ void virFree(void *ptrptr); > #define VIR_ALLOC_N(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count)) > > /** > + * VIR_ALLOC_VAR: > + * @ptr: pointer to hold address of allocated memory > + * @type: element type of trailing array > + * @count: number of array elements to allocate > + * > + * Allocate sizeof(*ptr) bytes plus an array of 'count' elements, each > + * sizeof('type'). This sort of allocation is useful for receiving > + * the data of certain ioctls and other APIs which return a struct in > + * which the last element is an array of undefined length. The caller > + * of this type of API is expected to know the length of the array > + * that will be returned and allocate a suitable buffer to contain the > + * returned data. > + * > + * Returns -1 on failure, 0 on success Hi Dave, This sounds like what at least gcc calls flexible array members, so you might want to let the macro name and/or description reflect that. Incidentally, there's an autoconf macro to detect whether a C compiler supports them: -- Macro: AC_C_FLEXIBLE_ARRAY_MEMBER If the C compiler supports flexible array members, define `FLEXIBLE_ARRAY_MEMBER' to nothing; otherwise define it to 1. That way, a declaration like this: struct s { size_t n_vals; double val[FLEXIBLE_ARRAY_MEMBER]; }; ... > + */ > +#define VIR_ALLOC_VAR(ptr, type, count) virAlloc(&(ptr), sizeof(*(ptr)) + (sizeof(type) * count)) > + > +/** > * VIR_REALLOC_N: > * @ptr: pointer to hold address of allocated memory > * @count: number of elements to allocate This new allocator should detect overflow, similarly to how virReallocN does, in case the product would overflow size_t: int virReallocN(void *ptrptr, size_t size, size_t count) { ... if (xalloc_oversized(count, size)) { errno = ENOMEM; return -1; } Finally, if you manage to leave it as a macro, you'll want to parenthesize "count" on the RHS. Otherwise, passing e.g., "n + 1" as the count will allocate too little space for any type with size larger than 1. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list