krahets/hello-algo · error · IndexError

队列已满

Error message

队列已满

What it means

Raised by `ArrayQueue#push` (array_queue.rb:31) when `size == capacity`. This queue is backed by a fixed-size array with no auto-resize; once the circular buffer is full there is no slot for the new element. Unlike a dynamic array, the capacity is set once at construction and never grows.

Source

Thrown at codes/ruby/chapter_stack_and_queue/array_queue.rb:31

  def initialize(size)
    @nums = Array.new(size, 0) # 用于存储队列元素的数组
    @front = 0 # 队首指针,指向队首元素
    @size = 0 # 队列长度
  end

  ### 获取队列的容量 ###
  def capacity
    @nums.length
  end

  ### 判断队列是否为空 ###
  def is_empty?
    size.zero?
  end

  ### 入队 ###
  def push(num)
    raise IndexError, '队列已满' if size == capacity

    # 计算队尾指针,指向队尾索引 + 1
    # 通过取余操作实现 rear 越过数组尾部后回到头部
    rear = (@front + size) % capacity
    # 将 num 添加至队尾
    @nums[rear] = num
    @size += 1
  end

  ### 出队 ###
  def pop
    num = peek
    # 队首指针向后移动一位,若越过尾部,则返回到数组头部
    @front = (@front + 1) % capacity
    @size -= 1
    num
  end

View on GitHub (pinned to 69932aed18)

Solutions

  1. Increase the capacity passed to `ArrayQueue.new(capacity)` to match peak enqueue depth.
  2. Drain (pop) elements before the buffer fills — check `queue.size < queue.capacity` before push.
  3. Switch to `LinkedListQueue` (no fixed capacity) if unbounded growth is acceptable.
  4. Rescue IndexError and apply backpressure (skip or retry the push).

Example fix

# before
queue.push(item)

# after
raise IndexError, 'Queue full' if queue.size == queue.capacity
queue.push(item) unless queue.size == queue.capacity
Defensive patterns

Strategy: validation

Validate before calling

raise IndexError, 'full' if queue.size == queue.capacity
queue.push(item)

Type guard

def queue_pushable?(queue)
  queue.respond_to?(:capacity) && queue.respond_to?(:size) && queue.size < queue.capacity
end

Try / catch

begin
  queue.push(item)
rescue IndexError
  # backpressure: drop, retry, or enqueue later
  false
end

Prevention

When it happens

Trigger: Calling `queue.push(num)` after enqueuing exactly `capacity` elements without dequeuing. The rear pointer `(@front + size) % capacity` would collide with `@front`, overwriting unread data, so the guard blocks the write.

Common situations: Producer faster than consumer in a bounded queue; forgot to drain the queue between batches; capacity sized too small for peak load; test that enqueues N+1 into a queue sized N.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/407ddd78411b382f. Report an issue: GitHub.