diff --git a/include/libcamera/request.h b/include/libcamera/request.h
index c9aeddb62680923dc3490a23dc6c3f70f70cc075..290983f613520f136f1d56100c665b0e3124ec02 100644
--- a/include/libcamera/request.h
+++ b/include/libcamera/request.h
@@ -49,7 +49,7 @@ public:
 
 	void reuse(ReuseFlag flags = Default);
 
-	ControlList &controls() { return *controls_; }
+	ControlList &controls() { return controls_; }
 	const ControlList &metadata() const;
 	const BufferMap &buffers() const { return bufferMap_; }
 	int addBuffer(const Stream *stream, FrameBuffer *buffer,
@@ -67,7 +67,7 @@ public:
 private:
 	LIBCAMERA_DISABLE_COPY(Request)
 
-	ControlList *controls_;
+	ControlList controls_;
 	BufferMap bufferMap_;
 
 	const uint64_t cookie_;
diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
index 0d6c4a0ce9aec5f328c1f66cea43abb37c82544a..57f1f060d5b48bfde97132793e96ef5ce33e252f 100644
--- a/src/libcamera/request.cpp
+++ b/src/libcamera/request.cpp
@@ -362,11 +362,9 @@ void Request::Private::timeout()
  */
 Request::Request(Camera *camera, uint64_t cookie)
 	: Extensible(std::make_unique<Private>(camera)),
+	  controls_(camera->controls(), camera->_d()->validator()),
 	  cookie_(cookie), status_(RequestPending)
 {
-	controls_ = new ControlList(camera->controls(),
-				    camera->_d()->validator());
-
 	LIBCAMERA_TRACEPOINT(request_construct, this);
 
 	LOG(Request, Debug) << "Created request - cookie: " << cookie_;
@@ -375,7 +373,6 @@ Request::Request(Camera *camera, uint64_t cookie)
 Request::~Request()
 {
 	LIBCAMERA_TRACEPOINT(request_destroy, this);
-	delete controls_;
 }
 
 /**
@@ -406,7 +403,7 @@ void Request::reuse(ReuseFlag flags)
 
 	status_ = RequestPending;
 
-	controls_->clear();
+	controls_.clear();
 	_d()->metadata_.clear();
 }
 
