krahets/hello-algo · error · IndexError

佇列已滿

Error message

佇列已滿

What it means

Raised by the push method of the ArrayQueue teaching class (a fixed-capacity circular-array queue) when size == capacity. Unlike MyList which auto-resizes, this queue has a hard capacity ceiling set at construction time. Once the backing array is full, no more elements can be enqueued until some are popped.

Source

Thrown at zh-hant/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. Check 'queue.size < queue.capacity' before calling push.
  2. Increase the capacity passed to ArrayQueue.new at construction time.
  3. Pop/consume elements before pushing more when the queue is near capacity.
  4. Wrap in begin/rescue IndexError to implement backpressure or retry logic.

Example fix

# before
loop { queue.push(produce_item) }  # raises once capacity is reached

# after
if queue.size < queue.capacity
  queue.push(produce_item)
else
  process(queue.pop)  # make room, then retry
  queue.push(produce_item)
end
Defensive patterns

Strategy: validation

Validate before calling

if queue.size < queue.capacity
  queue.push(num)
end

Type guard

# Ruby: safe push
def safe_push(queue, num)
  return false unless queue.size < queue.capacity
  queue.push(num)
  true
end

Try / catch

begin
  queue.push(num)
rescue IndexError
  # queue full: apply backpressure — pop and retry, or buffer
  process(queue.pop)
  retry
end

Prevention

When it happens

Trigger: Calling queue.push(num) after capacity elements have already been enqueued without intervening pops; creating a queue with a small capacity and exceeding it; a producer pushing faster than the consumer pops.

Common situations: Underestimating the required queue capacity at construction; unbounded producer loops without checking is_empty/push balance; testing with a tiny capacity (e.g., 3) and hitting the ceiling immediately.

Related errors


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