return from_tal_hdr(ignore_destroying_bit(t->parent_child)->parent);
}
-bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
+bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear)
{
struct tal_hdr *old_t, *t;
struct children *child;
struct prop_hdr **lenp;
struct length len;
- size_t extra = 0;
+ size_t extra = 0, elemsize = size;
old_t = debug_tal(to_tal_hdr(*ctxp));
/* Copy here, in case we're shrinking! */
len = *(struct length *)*lenp;
extra = extra_for_length(size);
- }
+ } else /* If we don't have an old length, we can't clear! */
+ assert(!clear);
t = resizefn(old_t, sizeof(struct tal_hdr) + size + extra);
if (!t) {
if (lenp) {
struct length *new_len;
+ /* Clear between old end and new end. */
+ if (clear && count > len.count) {
+ char *old_end = (char *)(t + 1) + len.count * elemsize;
+ memset(old_end, 0, elemsize * (count - len.count));
+ }
+
new_len = (struct length *)((char *)(t + 1) + size);
len.count = count;
*new_len = len;
assert(src < *ctxp
|| (char *)src >= (char *)(*ctxp) + (size * old_count));
- if (!tal_resize_(ctxp, size, old_count + count))
+ if (!tal_resize_(ctxp, size, old_count + count, false))
goto out;
memcpy((char *)*ctxp + size * old_count, src, count * size);
if (taken(p)) {
if (unlikely(!p))
return NULL;
- if (unlikely(!tal_resize_((void **)&p, size, n + extra)))
+ if (unlikely(!tal_resize_((void **)&p, size, n + extra, false)))
return tal_free(p);
if (unlikely(!tal_steal(ctx, p)))
return tal_free(p);
* tal_resize(&p, 100);
*/
#define tal_resize(p, count) \
- tal_resize_((void **)(p), sizeof**(p), (count))
+ tal_resize_((void **)(p), sizeof**(p), (count), false)
+
+/**
+ * tal_resizez - enlarge or reduce a tal_arr[z]; zero out extra.
+ * @p: A pointer to the tal allocated array to resize.
+ * @count: the number to allocate.
+ *
+ * This returns true on success (and may move *@p), or false on failure.
+ * If @p has a length property, it is updated on success.
+ * On expand, new elements are memset to 0 bytes.
+ *
+ * Example:
+ * tal_resizez(&p, 200);
+ */
+#define tal_resizez(p, count) \
+ tal_resize_((void **)(p), sizeof**(p), (count), true)
/**
* tal_steal - change the parent of a tal-allocated pointer.
tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t);
-bool tal_resize_(tal_t **ctxp, size_t size, size_t count);
+bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear);
bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count);
bool tal_add_destructor_(const tal_t *ctx, void (*destroy)(void *me));
strcpy(c[0], "hello");
tal_free(c[0]);
ok1(tal_first(parent) == NULL);
+
tal_free(parent);
tal_cleanup();
--- /dev/null
+#include <ccan/tal/tal.h>
+#include <ccan/tal/tal.c>
+#include <ccan/tap/tap.h>
+
+int main(void)
+{
+ char *parent, *c;
+ int i;
+
+ plan_tests(1 + 3 * 100 + 98);
+
+ parent = tal(NULL, char);
+ ok1(parent);
+
+ for (i = 0; i < 100; i++) {
+ c = tal_arr(parent, char, 1);
+ ok1(tal_resizez(&c, i));
+ ok1(tal_count(c) == i);
+ ok1(tal_parent(c) == parent);
+ if (i > 1)
+ ok1(c[i-1] == '\0');
+ }
+ tal_free(parent);
+
+ tal_cleanup();
+ return exit_status();
+}