From 0a5763ef49f7981a7a990a08bc0ce4f0a8ff36b1 Mon Sep 17 00:00:00 2001 From: Gereon Kremer Date: Mon, 6 Dec 2021 10:42:29 -0800 Subject: [PATCH] Use unique_ptr instead of raw pointers (#7749) This PR fixes a memory leak when invalid values are supplied to the stream options err, in or out. Whenever opening the stream would fail, we throw an exception and the created (though not properly opened) stream is leaked. We now properly wrap the streams in unqiue_ptrs directly on creation. --- src/options/managed_streams.cpp | 14 ++++++-------- src/options/managed_streams.h | 8 ++++---- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/options/managed_streams.cpp b/src/options/managed_streams.cpp index 90090df25..935b75a35 100644 --- a/src/options/managed_streams.cpp +++ b/src/options/managed_streams.cpp @@ -72,12 +72,11 @@ std::string cvc5_errno_failreason() namespace detail { -std::ostream* openOStream(const std::string& filename) +std::unique_ptr openOStream(const std::string& filename) { errno = 0; - std::ostream* res; - res = new std::ofstream(filename); - if (res == nullptr || !*res) + std::unique_ptr res = std::make_unique(filename); + if (!res || !*res) { std::stringstream ss; ss << "Cannot open file: `" << filename << "': " << cvc5_errno_failreason(); @@ -85,12 +84,11 @@ std::ostream* openOStream(const std::string& filename) } return res; } -std::istream* openIStream(const std::string& filename) +std::unique_ptr openIStream(const std::string& filename) { errno = 0; - std::istream* res; - res = new std::ifstream(filename); - if (res == nullptr || !*res) + std::unique_ptr res = std::make_unique(filename); + if (!res || !*res) { std::stringstream ss; ss << "Cannot open file: `" << filename << "': " << cvc5_errno_failreason(); diff --git a/src/options/managed_streams.h b/src/options/managed_streams.h index cf1820de6..830916b2f 100644 --- a/src/options/managed_streams.h +++ b/src/options/managed_streams.h @@ -31,12 +31,12 @@ namespace detail { * Open a file as an output stream and return it as a pointer. The caller * assumes the ownership of the returned pointer. */ -std::ostream* openOStream(const std::string& filename); +std::unique_ptr openOStream(const std::string& filename); /* * Open a file as an input stream and return it as a pointer. The caller * assumes the ownership of the returned pointer. */ -std::istream* openIStream(const std::string& filename); +std::unique_ptr openIStream(const std::string& filename); } // namespace detail /** @@ -64,13 +64,13 @@ class ManagedStream if constexpr (std::is_same::value) { d_nonowned = nullptr; - d_owned.reset(detail::openOStream(value)); + d_owned = detail::openOStream(value); d_description = value; } else if constexpr (std::is_same::value) { d_nonowned = nullptr; - d_owned.reset(detail::openIStream(value)); + d_owned = detail::openIStream(value); d_description = value; } } -- 2.30.2