def free(id)
      enclosing_range_index = @allocated_ranges.index { |range| range.last >= id && range.first <= id }
      enclosing_range = @allocated_ranges[enclosing_range_index]
      if enclosing_range.size == 1
        @allocated_ranges.delete(enclosing_range)
      elsif enclosing_range.first == id
        @allocated_ranges[enclosing_range_index] = (enclosing_range.first.succ..enclosing_range.last)
      elsif enclosing_range.last == id
        @allocated_ranges[enclosing_range_index] = (enclosing_range.first..enclosing_range.last.pred)
      else
        @allocated_ranges[enclosing_range_index] = (enclosing_range.first..id.pred)
        @allocated_ranges.insert(enclosing_range_index.succ, (id.succ..enclosing_range.last))
      end
    end
def free(id)
      enclosing_range_index = @allocated_ranges.index { |range| range.last >= id && range.first <= id }
      enclosing_range = @allocated_ranges[enclosing_range_index]
      if enclosing_range.size == 1
        @allocated_ranges.delete(enclosing_range)
      elsif enclosing_range.first == id
        @allocated_ranges[enclosing_range_index] = (enclosing_range.first.succ..enclosing_range.last)
      elsif enclosing_range.last == id
        @allocated_ranges[enclosing_range_index] = (enclosing_range.first..enclosing_range.last.pred)
      else
        @allocated_ranges[enclosing_range_index] = (enclosing_range.first..id.pred)
        @allocated_ranges.insert(enclosing_range_index.succ, (id.succ..enclosing_range.last))
      end
    end
Return +id+ back to the allocator so it can be allocated again in the future.
 @note trying to free an unallocated id will cause undefined behavior
 @return [void]