Specific std :: string behavior in visual studio?

I have a project in which I need to read / write large files.

I decided to use ifstream :: read () to put these files into memory in one pass, in std :: string. (this is the fastest way to do this in C ++: http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html and http: //insanecoding.blogspot. com / 2011/11 / reading-in-entire-file-at-once-in-c.html )

When switching between files, I then need to "reset" std :: string to use as the previous memory buffer (that is, to erase the char [] buffer in free memory)

I tried:

std::string::clear() std::string::assign("") std::string::erase(0, std::string::npos) std::string::resize(0) std::string::reserve(0) 

but in Visual Studio 2008 this does not free the memory used inside std :: string itself: its base buffer is not allocated.

The only way I found it was to call std :: string :: swap (std :: string ("")) to force the internal buffers to change between the actual std :: string and the empty one in the parameter.

I find this behavior a little strange ...

I tested only in Visual Studio 2008, I do not know if this is standard STL behavior or specific to MSVC.

Could you give me a hint?

+6
source share
1 answer

As Vlad and Alf noted, std::string().swap(the_string) is a C ++ 98 way to free up the_string capacity, and the_string.shrink_to_fit() is a C ++ 11 path.

As for why clear() , erase() , resize() , etc. they donโ€™t do this, itโ€™s an optimization to reduce allocations when using the string again and again. If clear() freed the line bandwidth, you would usually have to redistribute the same area at the next iteration, which would take some time when the implementation could save, while maintaining capacity. This implementation is not guaranteed by the standard, but it is very common in implementations.

reserve() documented using

The calling reserve () with the res_arg argument is less than the capacity (), which is actually an optional reduction requirement. A call with the res_arg <= size () parameter is actually an optional reduction requirement to match.

which implies that implementations are more likely to free up capacity when calling reserve() . If I read them correctly, libC ++ and libstdC ++ make room when you call reserve(0) , but for the VC ++ library it is possible to make the opposite choice.

Edit: As Penelope says, the behavior of std::string here tends to be exactly the same as the behavior of std::vector .

+4
source

Source: https://habr.com/ru/post/903112/


All Articles