diff --git a/src/queue/IdTable.hxx b/src/queue/IdTable.hxx
index 7c55869ff63c87bc6c7433cee9b8d39dfefbf124..93fae667a4c677058e4f8c348fc524341c1a43e5 100644
--- a/src/queue/IdTable.hxx
+++ b/src/queue/IdTable.hxx
@@ -31,6 +31,15 @@
 class IdTable {
 	const unsigned size;
 
+	/**
+	 * How many members of "data" are initialized?
+	 *
+	 * The initial value is 1 and not 0 because the first element
+	 * of the array is never used, because 0 is not a valid song
+	 * id.
+	 */
+	unsigned initialized = 1;
+
 	unsigned next;
 
 	int *const data;
@@ -38,7 +47,6 @@ class IdTable {
 public:
 	IdTable(unsigned _size) noexcept
 		:size(_size), next(1), data(new int[size]) {
-		std::fill_n(data, size, -1);
 	}
 
 	~IdTable() noexcept {
@@ -49,14 +57,14 @@ public:
 	IdTable &operator=(const IdTable &) = delete;
 
 	int IdToPosition(unsigned id) const noexcept {
-		return id < size
+		return id < initialized
 			? data[id]
 			: -1;
 	}
 
 	unsigned GenerateId() noexcept {
 		assert(next > 0);
-		assert(next < size);
+		assert(next <= initialized);
 
 		while (true) {
 			unsigned id = next;
@@ -65,6 +73,15 @@ public:
 			if (next == size)
 				next = 1;
 
+			if (id == initialized) {
+				/* the caller will initialize
+				   data[id] */
+				++initialized;
+				return id;
+			}
+
+			assert(id < initialized);
+
 			if (data[id] < 0)
 				return id;
 		}
@@ -72,19 +89,20 @@ public:
 
 	unsigned Insert(unsigned position) noexcept {
 		unsigned id = GenerateId();
+		assert(id < initialized);
 		data[id] = position;
 		return id;
 	}
 
 	void Move(unsigned id, unsigned position) noexcept {
-		assert(id < size);
+		assert(id < initialized);
 		assert(data[id] >= 0);
 
 		data[id] = position;
 	}
 
 	void Erase(unsigned id) noexcept {
-		assert(id < size);
+		assert(id < initialized);
 		assert(data[id] >= 0);
 
 		data[id] = -1;