What's the best way to read a file in using C++ and RAII? All the examples I've seen use something similar to the code below:
#include <iostream>
#include <fstream>
int main () {
std::ifstream is ("test.txt", std::ifstream::binary);
if (is) {
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);
char * buffer = new char [length]; // Seems wrong?
is.read (buffer, length);
delete[] buffer;
}
}
According to what I know of RAII it seems wrong to initialize a char pointer and manually remove it.
I've done something similar to:
#include <iostream>
#include <fstream>
int main () {
std::ifstream is ("test.txt", std::ifstream::binary);
if (is) {
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);
std::shared_ptr<char> buffer = std::make_shared<char>();
is.read (buffer.get(), length);
}
}
But I'm not sure if that's right either. I've also not been able to successfully cast std::shared_ptr<char>
to a std::shared_ptr<uint8_t>
if needed (or if it's possible, or if it even makes sense?).
char * buffer = new char [length]; // Seems wrong?
It's not wrong, just ... unsafe.
Safer implementations:
std::unique_ptr<char[]> buffer{new char [length]}; // note: use char[] as parameter
is.read (buffer.get(), length);
Better than previous:
std::vector<char> buffer{length, ' '};
is.read (buffer.data(), length);
or:
std::string buffer{length, ' '};
is.read (buffer.data(), length);
In particular, this is undefined behavior:
std::shared_ptr<char> buffer = std::make_shared<char>();
is.read (buffer, length);
because it allocates one character dynamically, then places up to length characters at that memory location. In practice, this is a buffer overflow, unless your length is always 1.