*(void**)ptrptr = NULL;
errno = save_errno;
}
+
+
+/**
+ * virDispose:
+ * @ptrptr: pointer to pointer for address of memory to be sanitized and freed
+ * @count: count of elements in the array to dispose
+ * @elemet_size: size of one element
+ * @countptr: pointer to the count variable to clear (may be NULL)
+ *
+ * Clear and release the chunk of memory in the pointer pointed to by 'prtptr'.
+ *
+ * If @countptr is provided, it's value is used instead of @count and it's set
+ * to 0 after clearing and freeing the memory.
+ *
+ * After release, 'ptrptr' will be updated to point to NULL.
+ */
+void virDispose(void *ptrptr,
+ size_t count,
+ size_t element_size,
+ size_t *countptr)
+{
+ int save_errno = errno;
+
+ if (countptr)
+ count = *countptr;
+
+ if (*(void**)ptrptr && count > 0)
+ memset(*(void **)ptrptr, 0, count * element_size);
+
+ free(*(void**)ptrptr);
+ *(void**)ptrptr = NULL;
+
+ if (countptr)
+ *countptr = 0;
+ errno = save_errno;
+}
ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
+void virDispose(void *ptrptr, size_t count, size_t element_size, size_t *countptr)
+ ATTRIBUTE_NONNULL(1);
+
/**
* VIR_ALLOC:
* @ptr: pointer to hold address of allocated memory
# define VIR_FREE(ptr) virFree(&(ptr))
# endif
+
+/**
+ * VIR_DISPOSE_N:
+ * @ptr: pointer holding address to be cleared and freed
+ * @count: count of elements in @ptr
+ *
+ * Clear the memory of the array of elemets pointed to by 'ptr' of 'count'
+ * elements and free it. Update the pointer/count to NULL/0.
+ *
+ * This macro is safe to use on arguments with side effects.
+ */
+# if !STATIC_ANALYSIS
+/* See explanation in VIR_FREE */
+# define VIR_DISPOSE_N(ptr, count) virDispose(1 ? (void *) &(ptr) : (ptr), 0, \
+ sizeof(*(ptr)), &(count))
+# else
+# define VIR_DISPOSE_N(ptr, count) virDispose(&(ptr), 0, sizeof(*(ptr)), &(count))
+# endif
+
+
+/**
+ * VIR_DISPOSE_STRING:
+ * @ptr: pointer to a string to be cleared and freed
+ *
+ * Clears the string and frees the corresponding memory.
+ *
+ * This macro is not safe to be used on arguments with side effects.
+ */
+# if !STATIC_ANALYSIS
+/* See explanation in VIR_FREE */
+# define VIR_DISPOSE_STRING(ptr) virDispose(1 ? (void *) &(ptr) : (ptr), \
+ (ptr) ? strlen((ptr)) : 0, 1, NULL)
+# else
+# define VIR_DISPOSE_STRING(ptr) virDispose(&(ptr), (ptr) ? strlen((ptr)) : 1, NULL)
+# endif
+
+
+/**
+ * VIR_DISPOSE:
+ * @ptr: pointer to memory to be cleared and freed
+ *
+ * Clears and frees the corresponding memory.
+ *
+ * This macro is safe to be used on arguments with side effects.
+ */
+# if !STATIC_ANALYSIS
+/* See explanation in VIR_FREE */
+# define VIR_DISPOSE(ptr) virDispose(1 ? (void *) &(ptr) : (ptr), 1, sizeof(*(ptr)), NULL)
+# else
+# define VIR_DISPOSE(ptr) virDispose(&(ptr), 1, sizeof(*(ptr)), NULL)
+# endif
+
+
void virAllocTestInit(void);
int virAllocTestCount(void);
void virAllocTestOOM(int n, int m);
}
+static int
+testDispose(const void *opaque ATTRIBUTE_UNUSED)
+{
+ int *num = NULL;
+ int *nums = NULL;
+ size_t nnums = 0;
+ char *str = NULL;
+
+ VIR_DISPOSE(num);
+ VIR_DISPOSE_N(nums, nnums);
+ VIR_DISPOSE_STRING(str);
+
+ nnums = 10;
+ VIR_DISPOSE_N(nums, nnums);
+
+ if (VIR_ALLOC(num) < 0)
+ return -1;
+
+ VIR_DISPOSE(num);
+
+ nnums = 10;
+ if (VIR_ALLOC_N(nums, nnums) < 0)
+ return -1;
+
+ VIR_DISPOSE_N(nums, nnums);
+
+ if (VIR_STRDUP(str, "test") < 0)
+ return -1;
+
+ VIR_DISPOSE_STRING(str);
+
+ return 0;
+}
+
+
static int
mymain(void)
{
ret = -1;
if (virtTestRun("insert array", testInsertArray, NULL) < 0)
ret = -1;
+ if (virtTestRun("dispose tests", testDispose, NULL) < 0)
+ ret = -1;
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}