AllocatorFree
Description
Free memory through an allocator. Typed paths dispatch directly to the concrete *_allocator_deallocate, whose size return value is the freed-byte count (discarded here – stats are updated inline inside the typed body, not through the return). Type-erased Allocator * routes through AllocatorFree_dyn, which adds the outer ValidateAllocator before delegating to the same typed body, so stats counter movement is identical on both paths.
Parameters
| Name | Direction | Description |
|---|---|---|
self |
in,out | Typed allocator pointer or Allocator *. |
ptr |
in | Pointer to the allocation, or NULL. |
Success
Function returns. The allocation is reclaimed.
Failure
No-op on NULL. A ptr the allocator does not own / has already freed / does not point at an allocation’s base aborts via LOG_FATAL.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
VecCharPtr.c:30:
char **str = (char **)copy;
if (str && *str) {
AllocatorFree((Allocator *)alloc, *str);
*str = NULL;
}- In
Io.c:3029:
if (previous) {
AllocatorFree(allocator_ptr, previous);
}- In
Io.c:3137:
(void)IntToBytesBE(value, buffer, byte_len);
if (!write_char_internal(o, fmt_info->flags, (Zstr)buffer, byte_len)) {
AllocatorFree(StrAllocator(o), buffer);
return false;
}- In
Io.c:3140:
return false;
}
AllocatorFree(StrAllocator(o), buffer);
return true;
}- In
Zstr.c:198:
if (*zs) {
AllocatorFree((Allocator *)alloc, (void *)*zs);
*zs = NULL;
}- In
Vec.c:54:
}
AllocatorFree(vec->allocator, vec->data);
}- In
Vec.c:143:
if (vec->length == 0) {
AllocatorFree(vec->allocator, vec->data);
vec->data = NULL;
vec->capacity = 0;- In
Map.c:453:
clear_map(map, entry_size, key_offset, key_size, value_offset, value_size, hash_offset);
AllocatorFree(map->allocator, map->entries);
AllocatorFree(map->allocator, map->states);- In
Map.c:454:
AllocatorFree(map->allocator, map->entries);
AllocatorFree(map->allocator, map->states);
MemSet(map, 0, sizeof(*map));- In
Map.c:511:
if ((map->length == 0) && (n == 0)) {
AllocatorFree(map->allocator, map->entries);
AllocatorFree(map->allocator, map->states);
map->entries = NULL;- In
Map.c:512:
if ((map->length == 0) && (n == 0)) {
AllocatorFree(map->allocator, map->entries);
AllocatorFree(map->allocator, map->states);
map->entries = NULL;
map->states = NULL;- In
Map.c:544:
if (!new_entries || !new_states) {
AllocatorFree(map->allocator, new_entries);
AllocatorFree(map->allocator, new_states);
// Restore the original table so the map stays usable.
- In
Map.c:545:
if (!new_entries || !new_states) {
AllocatorFree(map->allocator, new_entries);
AllocatorFree(map->allocator, new_states);
// Restore the original table so the map stays usable.
map->entries = old_entries;- In
Map.c:583:
// Probe-budget exhausted. Free the failed new table, double
// capacity, retry.
AllocatorFree(map->allocator, new_entries);
AllocatorFree(map->allocator, new_states);
size next_cap = new_capacity * 2;- In
Map.c:584:
// capacity, retry.
AllocatorFree(map->allocator, new_entries);
AllocatorFree(map->allocator, new_states);
size next_cap = new_capacity * 2;
if (next_cap <= new_capacity) {- In
Map.c:596:
}
AllocatorFree(map->allocator, old_entries);
AllocatorFree(map->allocator, old_states);- In
Map.c:597:
AllocatorFree(map->allocator, old_entries);
AllocatorFree(map->allocator, old_states);
(void)value_offset;- In
Map.c:1075:
hash
)) {
AllocatorFree(map->allocator, temp_entry);
return false;
}- In
Map.c:1091:
map->value_copy_deinit(temp_entry + value_offset, map->allocator);
}
AllocatorFree(map->allocator, temp_entry);
return false;
}- In
Map.c:1094:
return false;
}
AllocatorFree(map->allocator, temp_entry);
return true;
}- In
Map.c:1137:
map->value_copy_deinit(temp_value, map->allocator);
}
AllocatorFree(map->allocator, temp_value);
return false;
}- In
Map.c:1150:
if (map->value_copy_init) {
MemCopy(dst_value, temp_value, value_size);
AllocatorFree(map->allocator, temp_value);
} else {
MemCopy(dst_value, value, value_size);- In
Graph.c:127:
}
AllocatorFree(graph->allocator, data);
}- In
List.c:47:
new_node->data = AllocatorAlloc(list->allocator, item_size, true);
if (!new_node->data) {
AllocatorFree(list->allocator, new_node);
return false;
}- In
List.c:53:
if (list->copy_init) {
if (!list->copy_init(new_node->data, item_data, list->allocator)) {
AllocatorFree(list->allocator, new_node->data);
AllocatorFree(list->allocator, new_node);
return false;- In
List.c:54:
if (!list->copy_init(new_node->data, item_data, list->allocator)) {
AllocatorFree(list->allocator, new_node->data);
AllocatorFree(list->allocator, new_node);
return false;
}- In
List.c:125:
MemSet(node->data, 0, item_size);
AllocatorFree(list->allocator, node->data);
node->data = NULL;- In
List.c:139:
}
AllocatorFree(list->allocator, node->data);
node->data = NULL;
node = node->next;- In
List.c:165:
node->prev = NULL;
AllocatorFree(list->allocator, node);
node = next;
}- In
List.c:214:
}
AllocatorFree(list->allocator, data);
return true;
}- In
BitVec.c:93:
ValidateBitVec(bitvec);
if (bitvec->data) {
AllocatorFree(bitvec->allocator, bitvec->data);
}
MemSet(bitvec, 0, sizeof(*bitvec));- In
BitVec.c:164:
ValidateBitVec(bv);
if (bv->length == 0) {
AllocatorFree(bv->allocator, bv->data);
bv->data = NULL;
bv->capacity = 0;- In
BitVec.c:1513:
if (!prev_row || !curr_row) {
AllocatorFree(scratch, prev_row);
AllocatorFree(scratch, curr_row);
return false;- In
BitVec.c:1514:
if (!prev_row || !curr_row) {
AllocatorFree(scratch, prev_row);
AllocatorFree(scratch, curr_row);
return false;
}- In
BitVec.c:1546:
*out = prev_row[len2];
AllocatorFree(scratch, prev_row);
AllocatorFree(scratch, curr_row);- In
BitVec.c:1547:
*out = prev_row[len2];
AllocatorFree(scratch, prev_row);
AllocatorFree(scratch, curr_row);
return true;- In
Debug.c:257:
if (!MapInsertR(&self->live, user_p, rec)) {
if (self->config.force_page_backing)
AllocatorFree(&self->page, user_p);
else
AllocatorFree(&self->heap, user_p);- In
Debug.c:259:
AllocatorFree(&self->page, user_p);
else
AllocatorFree(&self->heap, user_p);
LOG_ERROR("DebugAllocator: failed to record allocation in live map");
#if FEATURE_ALLOC_STATS- In
Debug.c:338:
// entries-table lookup.
if (self->config.force_page_backing)
AllocatorFree(&self->page, ptr);
else
AllocatorFree(&self->heap, ptr);- In
Debug.c:340:
AllocatorFree(&self->page, ptr);
else
AllocatorFree(&self->heap, ptr);
return 0;
}- In
Debug.c:390:
}
} else {
AllocatorFree(&self->heap, ptr);
}
#if FEATURE_ALLOC_STATS- In
Socket.c:1063:
if (used_heap) {
AllocatorFree(&halloc, pfds);
HeapAllocatorDeinit(&halloc);
}- In
Pdb.c:479:
u8 *buf = AllocatorAlloc(BufAllocator(&self->data), sz, 0);
if (!buf) {
AllocatorFree(BufAllocator(&self->data), out);
return NULL;
}- In
Pdb.c:484:
bool read_ok = stream_read(self, section_hdr_stream, 0, buf, sz);
if (!read_ok) {
AllocatorFree(BufAllocator(&self->data), buf);
AllocatorFree(BufAllocator(&self->data), out);
return NULL;- In
Pdb.c:485:
if (!read_ok) {
AllocatorFree(BufAllocator(&self->data), buf);
AllocatorFree(BufAllocator(&self->data), out);
return NULL;
}- In
Pdb.c:494:
(void)BufReadU32LE(&rec, &out[i].virtual_address);
}
AllocatorFree(BufAllocator(&self->data), buf);
*out_count = n;
return out;- In
Pdb.c:553:
return false;
if (!stream_read(self, symrec_stream, 0, buf, sz)) {
AllocatorFree(BufAllocator(&self->data), buf);
return false;
}- In
Pdb.c:610:
pp.rva = rva;
if (!pool_append_cstr(pool, name, &pp.name_offset_in_pool)) {
AllocatorFree(BufAllocator(&self->data), buf);
return false;
}- In
Pdb.c:614:
}
if (!VecPushBackR(pending, pp)) {
AllocatorFree(BufAllocator(&self->data), buf);
return false;
}- In
Pdb.c:623:
}
AllocatorFree(BufAllocator(&self->data), buf);
return true;
}- In
Pdb.c:637:
if (!sections || num_sections == 0) {
if (sections)
AllocatorFree(BufAllocator(&self->data), sections);
return true; // can't compute RVAs without section table
}- In
Pdb.c:646:
PendingPubs pending = VecInitT(pending, BufAllocator(&self->data));
bool ok = walk_publics(self, dbi.symrec_stream, sections, num_sections, &self->name_pool, &pending);
AllocatorFree(BufAllocator(&self->data), sections);
if (!ok) {- In
Pdb.c:763:
if (alloc) {
if (self->stream_dir)
AllocatorFree(alloc, self->stream_dir);
if (self->stream_sizes)
AllocatorFree(alloc, self->stream_sizes);- In
Pdb.c:765:
AllocatorFree(alloc, self->stream_dir);
if (self->stream_sizes)
AllocatorFree(alloc, self->stream_sizes);
if (self->stream_blocks)
AllocatorFree(alloc, self->stream_blocks);- In
Pdb.c:767:
AllocatorFree(alloc, self->stream_sizes);
if (self->stream_blocks)
AllocatorFree(alloc, self->stream_blocks);
if (self->stream_block_counts)
AllocatorFree(alloc, self->stream_block_counts);- In
Pdb.c:769:
AllocatorFree(alloc, self->stream_blocks);
if (self->stream_block_counts)
AllocatorFree(alloc, self->stream_block_counts);
}
StrDeinit(&self->name_pool);- In
PageProtect.c:35:
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_READ_WRITE);
AllocatorFree(&page, region);
PageAllocatorDeinit(&page);
return ok; b->id = 2;
ok = (a->id == 1) && (b->id == 2);
AllocatorFree(alloc_base, a);
AllocatorFree(alloc_base, b);
} ok = (a->id == 1) && (b->id == 2);
AllocatorFree(alloc_base, a);
AllocatorFree(alloc_base, b);
} bool ok = (a != NULL);
AllocatorFree(alloc_base, a);
Node *b = (Node *)AllocatorAlloc(alloc_base, sizeof(Node), true);
ok = ok && (b == a); // The free list returned the same slot.
ok = ok && (b == a); // The free list returned the same slot.
AllocatorFree(alloc_base, b);
SlabAllocatorDeinit(&slab);
return ok; for (size i = 0; i < 600; i++) {
if (slots[i]) {
AllocatorFree(alloc_base, slots[i]);
}
} // walk both the free list (recycling) and the slab on growth.
for (size i = 0; ok && i < 200; i += 2) {
AllocatorFree(alloc_base, slots[i]);
slots[i] = NULL;
}
if (p) {
AllocatorFree(alloc_base, p);
}
SlabAllocatorDeinit(&slab); Allocator *a2 = ALLOCATOR_OF(&s2);
Node *p = (Node *)AllocatorAlloc(a1, sizeof(Node), false);
AllocatorFree(a2, p); // foreign to s2 -> LOG_FATAL
return false;
} Allocator *alloc = ALLOCATOR_OF(&slab);
u8 *p = (u8 *)AllocatorAlloc(alloc, sizeof(Node), false);
AllocatorFree(alloc, p + 1); // mis-aligned -> LOG_FATAL
return false;
} Allocator *alloc = ALLOCATOR_OF(&slab);
Node *p = (Node *)AllocatorAlloc(alloc, sizeof(Node), false);
AllocatorFree(alloc, p);
AllocatorFree(alloc, p); // bit already 0 -> LOG_FATAL
return false; Node *p = (Node *)AllocatorAlloc(alloc, sizeof(Node), false);
AllocatorFree(alloc, p);
AllocatorFree(alloc, p); // bit already 0 -> LOG_FATAL
return false;
} b->id = 2;
ok = (a->id == 1) && (b->id == 2);
AllocatorFree(alloc, a);
AllocatorFree(alloc, b);
} ok = (a->id == 1) && (b->id == 2);
AllocatorFree(alloc, a);
AllocatorFree(alloc, b);
} BudgetAllocator bp = BudgetAllocatorInit(buf, sizeof(buf), sizeof(Node));
Allocator *alloc = ALLOCATOR_OF(&bp);
AllocatorFree(alloc, NULL);
void *p = AllocatorAlloc(alloc, sizeof(Node), false);
bool ok = (p != NULL); bool ok = (p != NULL);
if (p)
AllocatorFree(alloc, p);
BudgetAllocatorDeinit(&bp);
return ok; Node *a = (Node *)AllocatorAlloc(alloc, sizeof(Node), true);
bool ok = (a != NULL);
AllocatorFree(alloc, a);
Node *b = (Node *)AllocatorAlloc(alloc, sizeof(Node), true);
// ctz finds the lowest clear bit, which is the one we just freed.
ok = ok && (b == a);
AllocatorFree(alloc, b);
BudgetAllocatorDeinit(&bp);
return ok;
if (a)
AllocatorFree(alloc, a);
if (b)
AllocatorFree(alloc, b); AllocatorFree(alloc, a);
if (b)
AllocatorFree(alloc, b);
if (c)
AllocatorFree(alloc, c); AllocatorFree(alloc, b);
if (c)
AllocatorFree(alloc, c);
BudgetAllocatorDeinit(&bp);
return ok;
if (p1)
AllocatorFree(alloc, p1);
if (p2)
AllocatorFree(alloc, p2); AllocatorFree(alloc, p1);
if (p2)
AllocatorFree(alloc, p2);
BudgetAllocatorDeinit(&bp);
return ok;
Node *p = (Node *)AllocatorAlloc(alloc1, sizeof(Node), false);
AllocatorFree(alloc2, p); // foreign to bp2 -> LOG_FATAL
return false;
} // exposing it would invite misuse); the test needs a non-NULL
// pointer in the bitmap region to exercise the foreign-ptr check.
AllocatorFree(alloc, bp.bitmap); // bitmap region -> LOG_FATAL
return false;
} Allocator *alloc = ALLOCATOR_OF(&bp);
char *p = (char *)AllocatorAlloc(alloc, sizeof(Node), false);
AllocatorFree(alloc, p + 1); // mis-aligned -> LOG_FATAL
return false;
} Allocator *alloc = ALLOCATOR_OF(&bp);
Node *p = (Node *)AllocatorAlloc(alloc, sizeof(Node), false);
AllocatorFree(alloc, p);
AllocatorFree(alloc, p); // bit already 0 -> LOG_FATAL
return false; Node *p = (Node *)AllocatorAlloc(alloc, sizeof(Node), false);
AllocatorFree(alloc, p);
AllocatorFree(alloc, p); // bit already 0 -> LOG_FATAL
return false;
} b[127] = 'B';
ok = (a[0] == 'A') && (a[31] == 'Z') && (b[0] == 'b') && (b[127] == 'B');
AllocatorFree(alloc, a);
AllocatorFree(alloc, b);
} ok = (a[0] == 'A') && (a[31] == 'Z') && (b[0] == 'b') && (b[127] == 'B');
AllocatorFree(alloc, a);
AllocatorFree(alloc, b);
} }
if (p)
AllocatorFree(alloc, p);
HeapAllocatorDeinit(&heap);
return ok;
// Must be silent + harmless.
AllocatorFree(alloc, NULL);
// Heap remains usable.
bool ok = (p != NULL);
if (p)
AllocatorFree(alloc, p);
HeapAllocatorDeinit(&heap);
return ok; bool ok = (a != NULL) && (b != NULL) && (c != NULL) && (a != b) && (b != c) && (a != c);
AllocatorFree(alloc, a);
AllocatorFree(alloc, b);
AllocatorFree(alloc, c);
AllocatorFree(alloc, a);
AllocatorFree(alloc, b);
AllocatorFree(alloc, c);
HeapAllocatorDeinit(&heap); AllocatorFree(alloc, a);
AllocatorFree(alloc, b);
AllocatorFree(alloc, c);
HeapAllocatorDeinit(&heap);
return ok;
void *a = AllocatorAlloc(alloc, 32, false);
AllocatorFree(alloc, a);
void *b = AllocatorAlloc(alloc, 32, false);
// ctz finds the LOWEST clear bit, which is the one we just freed.
if (b)
AllocatorFree(alloc, b);
HeapAllocatorDeinit(&heap);
return ok; for (u32 i = 0; i < N; i++) {
if (ptrs[i])
AllocatorFree(alloc, ptrs[i]);
}
AllocatorFree(alloc, ptrs); AllocatorFree(alloc, ptrs[i]);
}
AllocatorFree(alloc, ptrs);
HeapAllocatorDeinit(&heap);
return ok; for (u32 i = 0; i < 8; i++) {
if (ptrs[i])
AllocatorFree(alloc, ptrs[i]);
}
HeapAllocatorDeinit(&heap); p[n - 1] = 0xCD;
ok = (p[0] == 0xAB) && (p[n - 1] == 0xCD) && (HeapAllocatorXlCount(&heap) == 1);
AllocatorFree(alloc, p);
ok = ok && (HeapAllocatorXlCount(&heap) == 0);
}
if (p)
AllocatorFree(alloc, p);
HeapAllocatorDeinit(&heap);
return ok; u8 *grown = (u8 *)AllocatorRealloc(alloc, p, 30);
ok = (grown == p) && (grown[0] == 'x');
AllocatorFree(alloc, grown);
}
HeapAllocatorDeinit(&heap); ok = (grown != NULL) && (grown != p) && (grown[0] == 'h') && (grown[15] == '!');
if (grown)
AllocatorFree(alloc, grown);
}
HeapAllocatorDeinit(&heap); (HeapAllocatorPageCount(&h2) > 0);
AllocatorFree(alloc1, a);
AllocatorFree(alloc2, b);
HeapAllocatorDeinit(&h1);
AllocatorFree(alloc1, a);
AllocatorFree(alloc2, b);
HeapAllocatorDeinit(&h1);
HeapAllocatorDeinit(&h2); Allocator *alloc2 = ALLOCATOR_OF(&h2);
void *p = AllocatorAlloc(alloc1, 32, false);
AllocatorFree(alloc2, p); // foreign to h2 -> LOG_FATAL
return false; // unreachable
} Allocator *alloc = ALLOCATOR_OF(&heap);
void *p = AllocatorAlloc(alloc, 32, false);
AllocatorFree(alloc, p);
AllocatorFree(alloc, p); // bit already 0 -> LOG_FATAL
return false; void *p = AllocatorAlloc(alloc, 32, false);
AllocatorFree(alloc, p);
AllocatorFree(alloc, p); // bit already 0 -> LOG_FATAL
return false;
} Allocator *alloc = ALLOCATOR_OF(&heap);
u8 *p = (u8 *)AllocatorAlloc(alloc, 64, false);
AllocatorFree(alloc, p + 1); // mis-aligned -> LOG_FATAL
return false;
} size n = 16 * 1024;
u8 *p = (u8 *)AllocatorAlloc(alloc, n, false);
AllocatorFree(alloc, p + 128); // mid-allocation -> LOG_FATAL
return false;
}- In
Io.Blind.c:1113:
bool ok = (out != NULL) && s && (ZstrCompare(s, "hello world") == 0);
if (s)
AllocatorFree(&dbg.base, s);
ok = ok && (DebugAllocatorLiveCount(&dbg) == 0);
DebugAllocatorDeinit(&dbg); Allocator *alloc_base = ALLOCATOR_OF(&arena);
char stack_byte = 0;
AllocatorFree(alloc_base, &stack_byte); // -> LOG_FATAL
return false; // unreachable
}- In
AllocDebug.c:40:
ok = ok && DebugAllocatorLiveBytes(&dbg) == (64 + 128);
AllocatorFree(adbg, p1);
ok = ok && DebugAllocatorLiveCount(&dbg) == 1;
ok = ok && DebugAllocatorLiveBytes(&dbg) == 128;- In
AllocDebug.c:44:
ok = ok && DebugAllocatorLiveBytes(&dbg) == 128;
AllocatorFree(adbg, p2);
ok = ok && DebugAllocatorLiveCount(&dbg) == 0;
ok = ok && DebugAllocatorLiveBytes(&dbg) == 0;- In
AllocDebug.c:68:
Allocator *adbg = ALLOCATOR_OF(&dbg);
AllocatorFree(adbg, NULL); // no-op, must not crash
void *p = AllocatorAlloc(adbg, 32, false);
bool ok = (p != NULL) && (DebugAllocatorLiveCount(&dbg) == 1);- In
AllocDebug.c:72:
bool ok = (p != NULL) && (DebugAllocatorLiveCount(&dbg) == 1);
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);- In
AllocDebug.c:87:
u8 *buf = (u8 *)AllocatorAlloc(adbg, 16, true);
buf[16] = 0x55; // stomp first canary byte
AllocatorFree(adbg, buf);
bool ok = DebugAllocatorOverflows(&dbg) == 1;- In
AllocDebug.c:135:
HeapAllocatorDeinit(&scratch);
if (p1)
AllocatorFree(adbg, p1);
if (p2)
AllocatorFree(adbg, p2);- In
AllocDebug.c:137:
AllocatorFree(adbg, p1);
if (p2)
AllocatorFree(adbg, p2);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:159:
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:177:
ok = ok && (DebugAllocatorFreedCount(&dbg) == 0); // alloc doesn't push
AllocatorFree(adbg, p1);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 1);- In
AllocDebug.c:180:
ok = ok && (DebugAllocatorFreedCount(&dbg) == 1);
AllocatorFree(adbg, p2);
AllocatorFree(adbg, p3);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 3);- In
AllocDebug.c:181:
AllocatorFree(adbg, p2);
AllocatorFree(adbg, p3);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 3);- In
AllocDebug.c:210:
break;
}
AllocatorFree(adbg, p);
}
ok = ok && (DebugAllocatorFreedCount(&dbg) == 0);- In
AllocDebug.c:239:
if (grown)
AllocatorFree(adbg, grown);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:264:
bool ok = (p != NULL) && (DebugAllocatorLiveCount(&dbg) == 1);
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);- In
AllocDebug.c:284:
ok = ok && (((u64)p & 0xfff) == 0); // page-aligned
AllocatorFree(adbg, p);
ok = ok && (DebugAllocatorLiveCount(&dbg) == 0);- In
AllocDebug.c:299:
void *p = AllocatorAlloc(adbg, 32, true);
AllocatorFree(adbg, p);
AllocatorFree(adbg, p); // -> Heap LOG_FATAL
return false; // unreachable
- In
AllocDebug.c:300:
void *p = AllocatorAlloc(adbg, 32, true);
AllocatorFree(adbg, p);
AllocatorFree(adbg, p); // -> Heap LOG_FATAL
return false; // unreachable
}- In
AllocDebug.c:312:
u8 junk[64];
AllocatorFree(adbg, junk);
return false; // unreachable
}- In
AllocDebug.c:338:
// Leave canary byte 0 (index 16) intact; stomp byte 5 of the canary.
buf[16 + 5] = 0x77;
AllocatorFree(adbg, buf);
ok = ok && (DebugAllocatorOverflows(&dbg) == 1);- In
AllocDebug.c:378:
ok = ok && (live_n > 0) && (live_n <= DEBUG_ALLOCATOR_MAX_TRACE);
AllocatorFree(adbg, p);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 1);
ok = ok && (VecPtrAt(&dbg.freed, 0)->alloc_trace_n == live_n);- In
AllocDebug.c:406:
MemCopy(snapshot, rec->alloc_trace, (size)n * sizeof(StackFrame));
AllocatorFree(adbg, p);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 1);- In
AllocDebug.c:435:
void *p = AllocatorAlloc(adbg, 32, false);
bool ok = (p != NULL);
AllocatorFree(adbg, p);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 1);- In
AllocDebug.c:461:
void *p = AllocatorAlloc(adbg, 32, false);
bool ok = (p != NULL);
AllocatorFree(adbg, p);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 1);- In
AllocDebug.c:486:
void *p = AllocatorAlloc(adbg, 32, false);
bool ok = (p != NULL);
AllocatorFree(adbg, p);
ok = ok && (DebugAllocatorFreedCount(&dbg) == 1);- In
AllocDebug.c:506:
void *p = AllocatorAlloc(adbg, 32, false);
bool ok = (p != NULL);
AllocatorFree(adbg, p);
ok = ok && (AllocatorDeallocations(adbg) == 1);- In
AllocDebug.c:530:
ok = ok && (AllocatorBytesInUse(adbg) == (64 + 128));
AllocatorFree(adbg, a);
ok = ok && (AllocatorBytesInUse(adbg) == 128);- In
AllocDebug.c:533:
ok = ok && (AllocatorBytesInUse(adbg) == 128);
AllocatorFree(adbg, b);
ok = ok && (AllocatorBytesInUse(adbg) == 0);- In
AllocDebug.c:554:
for (u32 i = 0; ok && i < 32; i++)
ok = ok && (buf[i] == (u8)(i & 0xff));
AllocatorFree(adbg, buf);
ok = ok && (DebugAllocatorOverflows(&dbg) == 0);- In
AllocDebug.c:570:
void *p = AllocatorAlloc(adbg, 32, true);
AllocatorFree(adbg, p);
AllocatorFree(adbg, p); // -> LOG_FATAL
return false; // unreachable
- In
AllocDebug.c:571:
void *p = AllocatorAlloc(adbg, 32, true);
AllocatorFree(adbg, p);
AllocatorFree(adbg, p); // -> LOG_FATAL
return false; // unreachable
}- In
AllocDebug.c:583:
u8 junk[64];
AllocatorFree(adbg, junk); // -> LOG_FATAL (foreign ptr)
return false; // unreachable
}- In
AllocDebug.c:620:
if (p)
AllocatorFree(adbg, p);
ok = ok && (DebugAllocatorLiveBytes(&dbg) == 0);
DebugAllocatorDeinit(&dbg);- In
AllocDebug.c:638:
if (p1)
AllocatorFree(adbg, p1);
if (p2)
AllocatorFree(adbg, p2);- In
AllocDebug.c:640:
AllocatorFree(adbg, p1);
if (p2)
AllocatorFree(adbg, p2);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:658:
if (p1)
AllocatorFree(adbg, p1);
if (p2)
AllocatorFree(adbg, p2);- In
AllocDebug.c:660:
AllocatorFree(adbg, p1);
if (p2)
AllocatorFree(adbg, p2);
// still 100 after frees (cumulative)
ok = ok && (AllocatorBytesRequested(adbg) == 100);- In
AllocDebug.c:678:
if (p)
AllocatorFree(adbg, p);
ok = ok && (AllocatorBytesInUse(adbg) == 0);
DebugAllocatorDeinit(&dbg);- In
AllocDebug.c:697:
if (p)
AllocatorFree(adbg, p);
// peak does not shrink on free
ok = ok && (AllocatorPeakBytesInUse(adbg) == 512);- In
AllocDebug.c:719:
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:734:
bool ok = (big != NULL) && (AllocatorPeakBytesInUse(adbg) == 1000);
if (big)
AllocatorFree(adbg, big);
void *small = AllocatorAlloc(adbg, 8, false);- In
AllocDebug.c:743:
if (small)
AllocatorFree(adbg, small);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:792:
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:817:
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:841:
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:864:
buf[i] = (u8)(0xA0 + (i & 7)); // write the entire user region
}
AllocatorFree(adbg, buf); // must be a clean free, no overflow
ok = ok && (DebugAllocatorOverflows(&dbg) == 0);- In
AllocDebug.c:886:
buf[i] = 0xFF;
}
AllocatorFree(adbg, buf);
ok = ok && (DebugAllocatorOverflows(&dbg) == 0);
DebugAllocatorDeinit(&dbg);- In
AllocDebug.c:926:
// entry, no spurious bad-free / double-free.
for (u32 i = 0; i < N; i += 2) {
AllocatorFree(adbg, ps[i]);
ps[i] = NULL;
}- In
AllocDebug.c:930:
}
for (u32 i = 1; i < N; i += 2) {
AllocatorFree(adbg, ps[i]);
ps[i] = NULL;
}- In
AllocDebug.c:957:
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok;- In
AllocDebug.c:981:
if (ok)
buf[n] = 0x55; // one past the user region -> stomps canary[0]
AllocatorFree(adbg, buf);
// The canary sits exactly at offset n; a one-past write corrupts it.
if (grown)
AllocatorFree(adbg, grown);
DebugAllocatorDeinit(&dbg);
return ok;
if (shrunk)
AllocatorFree(adbg, shrunk);
// A max-copy mutant would have stomped the fresh canary; real code
// leaves it pristine.
HeapAllocatorDeinit(&scratch);
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok; void *p = AllocatorAlloc(adbg, 32, true);
bool ok = (p != NULL);
AllocatorFree(adbg, p);
// Live is now empty; break the bytes_in_use/live consistency
// the suite stay clean.
if (q)
AllocatorFree(adbg, q);
dbg.bytes_in_use = 0;
DebugAllocatorDeinit(&dbg); bool ok = (p != NULL);
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
if (q)
AllocatorFree(adbg, q);
if (p)
AllocatorFree(adbg, p); AllocatorFree(adbg, q);
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok; }
void *p = AllocatorAlloc(adbg, 32, true);
AllocatorFree(adbg, p); // captures the free trace from this deep stack
}- In
Map.Insert.c:320:
static size fail_alloc_deallocate(Allocator *self, void *ptr) {
FailAlloc *f = (FailAlloc *)(void *)self;
AllocatorFree(f->inner, ptr);
return 0;
} // free takes the `requested > bytes_in_use` underflow-guard else arm.
dbg.base.stats.bytes_in_use = 10;
AllocatorFree(adbg, p);
// Real: else arm sets stats.bytes_in_use = 0. Mutant: = 42.
HeapAllocatorDeinit(&scratch);
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok; HeapAllocatorDeinit(&scratch);
if (p)
AllocatorFree(adbg, p);
DebugAllocatorDeinit(&dbg);
return ok;- In
Vec.Complex.c:30:
#define fixture_malloc(n) AllocatorAlloc(fixture_alloc(), (n), false)
#define fixture_free(p) AllocatorFree(fixture_alloc(), (p))
// Cast off const: `zstr_dup` returns a `Zstr` because the project convention
((char *)ptr)[127] = 'y';
ok = ok && (((char *)ptr)[0] == 'x') && (((char *)ptr)[127] == 'y');
AllocatorFree(&alloc, ptr);
} ok = ok && (shrunk != NULL) && (shrunk[0] == 'a');
if (shrunk) {
AllocatorFree(&alloc, shrunk);
}
}
if (ptr) {
AllocatorFree(&alloc, ptr);
}
if (p1) {
AllocatorFree(&alloc, p1);
}
// EntryCount drops to 1 (p1 moved to free_entries[]).
if (p2) {
AllocatorFree(&alloc, p2);
}
if (PageAllocatorEntryCount(&alloc) != 0) { static bool test_al_free_validates_magic(void) {
Allocator a = mock_make_bad_magic();
AllocatorFree(&a, mock_backing); // real -> Validate -> LOG_FATAL
return false;
} && (AllocatorBytesRequested(alloc) == 0u);
AllocatorFree(alloc, p);
HeapAllocatorDeinit(&heap);
return ok;
Last updated on