Use unique_ptr instead of raw pointers (#7749)
authorGereon Kremer <gkremer@stanford.edu>
Mon, 6 Dec 2021 18:42:29 +0000 (10:42 -0800)
committerGitHub <noreply@github.com>
Mon, 6 Dec 2021 18:42:29 +0000 (18:42 +0000)
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
src/options/managed_streams.h

index 90090df257bf2378dd89fed0742074606cf10da3..935b75a356339b51b9ae21833473f0510db8685c 100644 (file)
@@ -72,12 +72,11 @@ std::string cvc5_errno_failreason()
 
 namespace detail {
 
-std::ostream* openOStream(const std::string& filename)
+std::unique_ptr<std::ostream> openOStream(const std::string& filename)
 {
   errno = 0;
-  std::ostream* res;
-  res = new std::ofstream(filename);
-  if (res == nullptr || !*res)
+  std::unique_ptr<std::ostream> res = std::make_unique<std::ofstream>(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<std::istream> openIStream(const std::string& filename)
 {
   errno = 0;
-  std::istream* res;
-  res = new std::ifstream(filename);
-  if (res == nullptr || !*res)
+  std::unique_ptr<std::istream> res = std::make_unique<std::ifstream>(filename);
+  if (!res || !*res)
   {
     std::stringstream ss;
     ss << "Cannot open file: `" << filename << "': " << cvc5_errno_failreason();
index cf1820de6d551dec0d72fff0d3f26bf782627f29..830916b2f3f18d8382436a77b8a421a6c981b3f1 100644 (file)
@@ -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<std::ostream> 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<std::istream> openIStream(const std::string& filename);
 }  // namespace detail
 
 /**
@@ -64,13 +64,13 @@ class ManagedStream
     if constexpr (std::is_same<Stream, std::ostream>::value)
     {
       d_nonowned = nullptr;
-      d_owned.reset(detail::openOStream(value));
+      d_owned = detail::openOStream(value);
       d_description = value;
     }
     else if constexpr (std::is_same<Stream, std::istream>::value)
     {
       d_nonowned = nullptr;
-      d_owned.reset(detail::openIStream(value));
+      d_owned = detail::openIStream(value);
       d_description = value;
     }
   }