How to pre-allocate memory for a std::string object?

This isn't so much an answer in itself, as a kind of a comment on/summary/comparison of a couple of other answers (as well as a quick demonstration of why I've recommended the style of code @Johannes - litb gives in his answer). Since @sbi posted an alternative that looked pretty good, and (especially) avoided the extra copy involved in reading into a stringstream, then using the .str() member to get a string, I decided to write up a quick comparison of the two: Edit: I've added a third test case using @Tyler McHenry's istreambuf_iterator-based code, and added a line to print out the length of each string that was read to ensure that the optimizer didn't optimize away the reading because the result was never used. Edit2: And now, code from Martin York has been added as well... #include #include #include #include #include #include int main() { std::ostringstream os; std::ifstream file("equivs2.

Txt"); clock_t start1 = clock(); os (pos)); s2. Assign(std::istream_iterator(file), std::istream_iterator()); clock_t stop2 = clock(); std::cout Seekg(0, std::ios::end); s3. Reserve(file.tellg()); file.

Seekg(0, std::ios::beg); s3. Assign((std::istreambuf_iterator(file)), std::istreambuf_iterator()); clock_t stop3 = clock(); std::cout Resize(file.tellg()); file. Seekg(0, std::ios::beg); file.

Read(&s40, s4.length()); clock_t stop4 = clock(); std::cout Length = " Length = 7669436 s4. Length = 7669436 Time using rdbuf: 184 Time using istream_iterator: 1332 Time using istreambuf_iterator: 249 Time using read: 48 Then with gcc (cygwin): s.length() = 8278035 s2. Length = 6390689 s3.

Length = 8278035 s4. Length = 8278035 Time using rdbuf: 62 Time using istream_iterator: 2199 Time using istreambuf_iterator: 156 Time using read: 16 end of edit -- the conclusions remain, though the winner has changed -- Martin's code is clearly the fastest. The results are quite consistent with respect to which is fastest and slowest.

The only inconsistency is with how much faster or slower one is than another. Though the placements are the same, the speed differences are much larger with gcc than with VC++.

Sort of what I thought initially: It's much easier to optimize the char-by-char read of opThanks for timing it! – Johannes Schaub - litb Jul 21 '10 at 21:49.

Just for fun, here's another way to do this: // Beware, brain-compiled code ahead! Std::ifstream ifs( /* ... */ ); if(!ifs.good() ) return; // whatever std::string str; ifs. Seekg( 0, std::ios_base::end ); const std::streampos pos = ifs.tellg(); ifs.

Seekg( 0, std::ios_base::beg ); if( pos! =std::streampos(-1) ) // can get stream size? Str.

Reserve(static_cast(pos)); str. Assign( std::istream_iterator(ifs) , std::istream_iterator() ); I hope I didn't blow it too badly.

2 +1, was waiting for someone to elaborate stream iterator based code :) – bobah Jul 21 '10 at 20:56 +1, for flexible Brain-Compiler is okay with missing } ;) – Nasgul Jul 21 '10 at 21:02 @Gollum: I freely admit I copied those seekg() lines straight out of some code of mine (which fills a string with a file's content) and overlooked the {. I fixed it, but that's what that disclaimer is for, anyway. – sbi Jul 21 '10 at 21:05.

This should be all you need: ostringstream os; ifstream file("name. Txt"); os > os.rdbuf(); // This does not skip it file >> noskipws >> os.rdbuf(); These functions are described as reading the stream character by character though (not sure what optimizations are possible here, though), I haven't timed these to determine their speed.

1 beating me. :( – GMan Jul 21 '10 at 20:34 1 this does copy twice, once to ostringstream buffer and second time to s – Nasgul Jul 21 '10 at 20:35 @Johannes, I was assuming the string memory to be contagious buffer, but after reading @GMan 's answer I realized that there is no way around the copying. – Nasgul Jul 21 '10 at 20:41 @Gollum: As I pointed out in an answer yesterday, I've used code like the above a lot without a problem, but if the extra copy causes a real problem, consider a previous answer Martin York pointed out yesterday: stackoverflow.com/questions/132358/….– Jerry Coffin Jul 21 '10 at 20:42 @Jerry, checked that answer, but that uses vector which again needs to be copied in to a string – Nasgul Jul 21 '10 at 20:45.

It seems that you are asking how to do a CString::GetBuffer, ReleaseBuffer type operation with std::string. I don't know of any way to do this directly, an easy way would be to just create a raw C style buffer, read into the buffer, then copy the buffer to a std::string using assign or whatever. Of course you would have to worry about buffer overrun issues etc., also I would use a std::autoptr to manage the raw buffer pointer, to enusre deallocation on exception etc. This is a bit simpler than using stringstream etc. I can provide an example if needed.

Devin Ellingson.

1 auto_ptr doesn't handle array types correctly. Just use std::vector. (Also, signing posts is frowned upon; your name is under everything you do.) – GMan Jul 22 '10 at 3:53 Thanks GMan, I forgot about that problem, auto_ptr always calls delete instead of delete , which is whatwould be needed in this case.

You could just create a simple array_auto_ptr class or as you say use std::vector. – DevinEllingson Jul 22 '10 at 18:58.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions