struct varray *varray_init(void) { struct varray *varray = malloc_checked(sizeof(struct varray)); varray->blocks = NULL; varray->read_block = -1; varray->last_block = -1; varray->read_block_pos = blocklen; varray->last_block_pos = blocklen; return varray; }
struct path *varray_add(struct varray *varray, struct path path) { struct path *store; if(likely(varray->last_block_pos < blocklen)) { store = varray->blocks[varray->last_block] + varray->last_block_pos++; } else { varray->blocks = realloc_checked(varray->blocks, (++varray->last_block + 1) * sizeof(*varray->blocks)); store = varray->blocks[varray->last_block] = malloc_checked(BLOCKSIZE); varray->last_block_pos = 1; } *store = path; return store; }
/******************************************************************************\ Reallocate [ptr] to [size] bytes large. Abort on error. String all the allocated chunks into a linked list and tracks information about the memory and where it was allocated from. This is used later in C_free() and C_check_leaks() to detect various errors. \******************************************************************************/ static void *realloc_checked(const char *file, int line, const char *function, void *ptr, size_t size) { c_mem_tag_t *tag, *prev_tag, *old_tag; size_t real_size; if (!ptr) return malloc_checked(file, line, function, size); if (!(tag = find_tag(ptr, &prev_tag))) C_error_full(file, line, function, "Trying to reallocate unallocated address (0x%x)", ptr); old_tag = tag; real_size = size + sizeof (c_mem_tag_t) + NO_MANS_LAND_SIZE; tag = realloc((char *)ptr - sizeof (c_mem_tag_t), real_size); if (!tag) C_error("Out of memory, %s() (%s:%d) tried to allocate %d " "bytes", function, file, line, size ); if (prev_tag) prev_tag->next = tag; if (old_tag == mem_root) mem_root = tag; mem_bytes += size - tag->size; if (size > tag->size) { mem_calls++; if (mem_bytes > mem_bytes_max) mem_bytes_max = mem_bytes; } tag->size = size; tag->alloc_file = file; tag->alloc_line = line; tag->alloc_func = function; tag->data = (char *)tag + sizeof (c_mem_tag_t); memset((char *)tag->data + size, NO_MANS_LAND_BYTE, NO_MANS_LAND_SIZE); return tag->data; }