std::vector vs std::unique_ptr

Started by
27 comments, last by rnlf_in_space 11 years, 9 months ago
Oh, so you did. Nobody responded about it though. Oh well.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Advertisement
I am using unique_ptr<x[]> whenever I want to read large arrays directly from binary files. It skips vector's default-initialization of the allocated memory and allows efficient use of istream::read instead of per-element-read operations.

Does anyone know a way to get these advantages (maybe there are even specific compiler optimizations for this case?) by using a vector instead of unique_ptr<x[]>?

Cheers, rnlf
I'm not sure if you can bypass the default initialization, but &myvector[0] (or better myvector.data() on C++11) points to the exact same block of memory you can use for istream::reads.
Yes, I know that. But for large chunks of memory (like large textures, vertex or audio data) I would like to circumvent the initialization. I think, using a unique_ptr ist reasonably secure and it is also quite convenient, since the size of the block is always known beforehand and will never be resized.

i just thought, maybe someone knows a way to get the best out of both worlds ;-)
I keep it simple and just use [font=courier new,courier,monospace]char*[/font] along with simply disallowing transfer/modification of the buffer's initial lifetime (which is assigned to a scope-stack)... that's probably not the most popular C++-esque answer, but it works for me, is dead simple and pretty hard to screw up tongue.png
@rnlf: I googled your question and found this. For those too lazy to click the link, the relevant code is:

#include<iterator>

std::ifstream testFile("testfile", std::ios::binary);
// ...
std::vector<char> fileContents;
fileContents.reserve(fileSize);
fileContents.assign(std::istreambuf_iterator<char>(testFile),
std::istreambuf_iterator<char>());


All credits to wilhelmtell for the code. Whether or not this is more optimal though, is up for debate, as I think it has potential to be slightly slower (but not faster) than just a simple std::unique_ptr (I say it could potentially be slightly slower because it depends on exactly how the C++ implementation implements std::ifstream::read() and the above code... buffering (and copying into a temporary, intermediate buffer) can make a big difference, and I imagine that a single std::ifstream::read() may potentially just read directly into the buffer, while the std::istreambuf_iterator may potentially cause data to be read into an intermediate buffer before copying it over...). If you care that much, just try each one, look at the asm, and profile.

I might just go for a std::unique_ptr, for simplicity's sake.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
@Cornstalks: when I initially googled for the topic, I found this stackoverflow thread as well, but just as James McNellis writes a few comments below, this does not actually seem to be standard compliant. I still have to look it up in the standard to get confirmation though.

it seems to me, there really isn't a nice and correct way to achieve this by using a vector (and in fact, there is no real benefit using a vector instead: Freeing of the array is done automatically when it goes out of scope, it is exception safe, it is not easier to make mistakes with the arrays size and indexed access as it would be with a vector and it saves the overhead of the - in this case - unneccessary management data). Plus it has a much more natural syntax that does not feel like abuse of a vector's interface.

So I guess I'll just stick to it. Thank you anyway, I feel much more confident using this versiow now :-)

Cheers
rnlf

@Cornstalks: when I initially googled for the topic, I found this stackoverflow thread as well, but just as James McNellis writes a few comments below, this does not actually seem to be standard compliant. I still have to look it up in the standard to get confirmation though.

That was because his first reversion was, which he fixed (see his response to James McNellis's comment).

But yeah, I like std::unique_ptr for this better, anyway. It makes it a little clearer you have no plans on resizing the buffer, anyway.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Ah, I'm sorry. Missed the two hidden answers. But I'll stick to unique_ptr, just as you said.

This topic is closed to new replies.

Advertisement