MaPo
MaPo

Reputation: 855

Dereference unique_ptr to a reference

The following (unsafe) code works

#include <iostream>
#include <fstream>

std::ofstream* create_unsafe_stream(const char* filename) {
    return new std::ofstream {filename};
}

int main () {
    std::ofstream& u_out = *create_unsafe_stream("foo.txt");
    u_out << "foo\n" ;
    delete &u_out;
    return 0;
}

I tried to produce a safer version

#include <iostream>
#include <fstream>
#include <memory>

using stream_ptr = std::unique_ptr<std::ostream>;

stream_ptr create_safe_stream(const char* filename) {
    return stream_ptr{ new std::ofstream {filename}};
}

int main() {
  std::ostream& s_out = *create_safe_stream("foo.txt");
  s_out << "foo\n" << std::endl; 
  return 0
}

Which compiles but, when I run it give me a segmentation fault. I was thinking that the problem is caused by the unique_ptr going out of the scope. So I tried to modify a bit the main to

int main() {
   stream_ptr ofile = create_safe_stream("foo.txt");
   std::ostream& s_out = *ofile;
   s_out << "foo\n"; 
}

which works again.

QUESTION

Is there a way not to use an 'intermediate' variable like ofile and doing all in a line?

EDIT

The function create_safe_stream is a toy model of what I want, that is this function may return either the std::ofstream to that file or the std::cout, so I think I really need to return a pointer to the base class std::ostream. How can I do?

Upvotes: 3

Views: 1947

Answers (1)

Hatted Rooster
Hatted Rooster

Reputation: 36503

Your assumption is correct. create_safe_stream returns a std::unique_ptr which immediately goes out of scope and thus the raw resource it holds is deleted and trying to use it is UB.

The way to not use an intermediate variable and doing it all in one line is by just returning a std::ofstream object instead:

std::ofstream create_safe_stream(const char* filename) {
    return std::ofstream {filename};
}

int main() {
  std::ostream s_out = create_safe_stream("foo.txt");
  s_out << "foo\n" << std::endl; 
  return 0;
}

Upvotes: 3

Related Questions