krahets/hello-algo · error · Error

佇列為空

Error message

佇列為空

What it means

An Error '佇列為空' ('queue is empty') thrown by peek() in ArrayQueue (array_queue.ts:58). peek() returns nums[front]; on an empty queue front is stale, so the guard prevents returning garbage. pop() calls peek() first, so the same guard blocks popping an empty queue.

Source

Thrown at zh-hant/codes/typescript/chapter_stack_and_queue/array_queue.ts:58

        // 透過取餘操作實現 rear 越過陣列尾部後回到頭部
        const rear = (this.front + this.queSize) % this.capacity;
        // 將 num 新增至佇列尾
        this.nums[rear] = num;
        this.queSize++;
    }

    /* 出列 */
    pop(): number {
        const num = this.peek();
        // 佇列首指標向後移動一位,若越過尾部,則返回到陣列頭部
        this.front = (this.front + 1) % this.capacity;
        this.queSize--;
        return num;
    }

    /* 訪問佇列首元素 */
    peek(): number {
        if (this.isEmpty()) throw new Error('佇列為空');
        return this.nums[this.front];
    }

    /* 返回 Array */
    toArray(): number[] {
        // 僅轉換有效長度範圍內的串列元素
        const arr = new Array(this.size);
        for (let i = 0, j = this.front; i < this.size; i++, j++) {
            arr[i] = this.nums[j % this.capacity];
        }
        return arr;
    }
}

/* Driver Code */
/* 初始化佇列 */
const capacity = 10;
const queue = new ArrayQueue(capacity);

View on GitHub (pinned to 69932aed18)

Solutions

  1. Check queue.isEmpty() before peek/pop.
  2. Consume with `while (!queue.isEmpty())` or coordinate with the producer so pops never exceed pushes.
  3. Use size() for the element count, not the backing capacity.
  4. Return an optional/sentinel from a wrapper when empty is a normal condition.

Example fix

// before: popping an empty queue throws
const head = queue.pop();

// after: guard with emptiness check
const head = queue.isEmpty() ? undefined : queue.pop();
Defensive patterns

Strategy: validation

Validate before calling

// Guard ArrayQueue peek/pop
function safePop(queue: ArrayQueue): number | undefined {
    return queue.isEmpty() ? undefined : queue.pop();
}
while (!queue.isEmpty()) {
    const head = queue.pop();
}

Type guard

const nonEmpty = (queue: ArrayQueue): boolean => !queue.isEmpty();

Try / catch

try {
    const head = queue.pop();
} catch (e) {
    if (e instanceof Error && e.message === '佇列為空') {
        // queue empty; handle gracefully
    } else throw e;
}

Prevention

When it happens

Trigger: Calling queue.peek() or queue.pop() when queue.isEmpty() is true (queSize === 0). Popping more than was pushed, or operating on a queue that was never filled after construction.

Common situations: Off-by-one in a consumer loop; FIFO producer/consumer where the consumer outruns the producer; assuming the queue has data because capacity > 0; mixing this ring-array queue's API with a list-based one and forgetting the explicit emptiness check.

Related errors


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