title: file input and pointer ownership semantics
body: <p>There are two ways that I know of to read file contents to a C-style string. The reason I need a C-style string and not a <code>unique_ptr&lt;string&gt;</code> is because I will be passing this data to a C function, <a href="http://matze.github.io/clib-doc/gumbo-parser/index.html#parser_8c_1acc6867266c808111d0c38b790f5a01fa" rel="nofollow"><code>gumbo_parse()</code></a> whose parameter is a C-style string, and this way I avoid the overhead of a <code>unique_ptr&lt;string&gt;</code>. I am open to arguments against my decision.</p>
  
  <pre><code>std::ifstream ifs(bf::path("..."));                                              // Input file stream
  </code></pre>
  
  <p>First way:</p>
  
  <pre><code>std::filebuf * ptr_fbuff = ifs.rdbuf();                                         // Buffer to file contents.
  std::size_t fbuff_size = ptr_fbuff-&gt;pubseekoff(0, ifs.end, std::ios_base::in);  // Get offset from 0 to end of buffer.
  ptr_fbuff-&gt;pubseekpos(0, std::ios_base::in);                                    // Move buffer position back to beginning.
  char * buffer = new char[fbuff_size];                                           // Buffer to store file data.
  ptr_fbuff-&gt;sgetn(buffer, fbuff_size);                                           // Get file data.
  </code></pre>
  
  <p>Second way:</p>
  
  <pre><code>std::stringstream sstm_buffer;                                                  // Buffer to file contents.
  sstm_buffer &lt;&lt; ifs.rdbuf();                                                     // Read file contents to sstm.
  const std::string &amp; str_buffer = sstm_buffer.str();                             // Get underlying string from sstm.
  char * buffer = new char[str_buffer.size()];                                    // Buffer to store file data.
  str_buffer.copy(buffer, str_buffer.size());                                     // Copy file contents to buffer.
  </code></pre>
  
  <p>Do stuff:</p>
  
  <pre><code>GumboOutput * ptr_outpt = gumbo_parse(buffer);
  //...
  </code></pre>
  
  <p>Close file:</p>
  
  <pre><code>gumbo_destroy_output(&amp;kGumboDefaultOptions, ptr_outpt);
  ifs.close();                                                                    // Close stream to file.
  delete[] buffer;                                                                // Delete allocated buffer.
  </code></pre>
  
  <p>What are the differences between the two in terms of memory cost and speed. Clearly one uses a Stringstream as a buffer before putting the contents into the C-style string, and the other uses a filebuf before putting the contents into a C-style string.</p>
  
  <p>Now to my second question. Ownership semantics and memory allocation. Does the ifstream allocate any memory in the heap for the buffer returned from rdbuf? Am I responsible for deleting the buffer returned from rdbuf? If it doesn't, say I'm reading a huge file... isn't that potentially a LOT of data to be storing in the stack?</p>
  
  <p>Edit:</p>
  
  <pre><code>std::unique_ptr&lt;std::string&gt; mytype::my_func(const std::string &amp; path)
  {
      std::ifstream ifs(path);                                            // Input file stream
      std::stringstream sstm_buffer;                                      // Buffer to file contents.
      sstm_buffer &lt;&lt; ifs.rdbuf();                                         // Read file contents to sstm.
      ifs.close();                                                        // Close stream to file.
      auto ptr_buffer = std::make_unique&lt;std::string&gt;(sstm_buffer.str()); // Pointer to copy of sstm buffer contents.
      return std::move(ptr_buffer);                                       // Return pointer.
  }
  </code></pre>
  
  <p>Edit2:</p>
  
  <pre><code>std::string mytype::my_func(const std::string &amp; path) const
  {
      std::ifstream ifs(path);
      std::stringstream sstm_buf;
      sstm_buf &lt;&lt; ifs.rdbuf();
      ifs.close();
      return sstm_buf.str();
  }
  </code></pre>
  
  <p>Edit3:</p>
  
  <pre><code>std::string psclient::file_get(const std::string &amp; path) const
  {
      std::ifstream ifs(path);    // Stream to file (Automatically close() on ~).
      std::ostringstream reader;  // Stream to read file contents.
      reader &lt;&lt; ifs.rdbuf();      // Read in file contents.
      return reader.str();        // Return a move instead of copy (Done implicitly).
  }
  </code></pre>