Is it reasonable to use std::basic_string<t> as a contiguous buffer when targeting C++03?

扶醉桌前 提交于 2019-11-26 17:47:53

I'd consider it quite safe to assume that std::string allocates its storage contiguously.

At the present time, all known implementations of std::string allocate space contiguously.

Moreover, the current draft of C++ 0x (N3000) [Edit: Warning, direct link to large PDF] requires that the space be allocated contiguously (§21.4.1/5):

The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size().

As such, the chances of a current or future implementation of std::string using non-contiguous storage are essentially nil.

Michael Burr

A while back there was a question about being able to write to the storage for a std::string as if it were an array of characters, and it hinged on whether the contents of a std::string were contiguous:

My answer indicated that according to a couple well regarded sources (Herb Sutter and Matt Austern) the current C++ standard does require std::string to store its data contiguous under certain conditions (once you call str[0] assuming str is a std::string) and that that fact pretty much forces the hand of any implementation.

Basically, if you combine the promises made by string::data() and string::operator[]() you conclude that &str[0] needs to return a contiguous buffer. Therefore Austern suggests that the committee just make that explicit, and apparently that's what'll happen in the 0x standard (or are they calling it the 1x standard now?).

So strictly speaking an implementation doesn't have to implement std::string using contiguous storage, but it has to do so pretty much on demand. And your example code does just that by passing in &buffer[0].

Links:

The result is undefined and I would not do it. The cost of reading into a vector and then converting to a string is trivial in modern c++ heaps. VS the risk that your code will die in windows 9

also, doesnt that need a const_cast on &buffer[0]?

Edit: You want to call &buffer[0], not buffer.data(), because [] returns a non-const reference and does notify the object that its contents can change unexpectedly.


It would be cleaner to do buffer.data(), but you should worry less about contiguous memory than memory shared between structures. string implementations can and do expect to be told when an object is being modified. string::data specifically requires that the program not modify the internal buffer returned.

VERY high chances that some implementation will create one buffer for all strings uninitialized besides having length set to 10 or whatever.

Use a vector or even an array with new[]/delete[]. If you really can't copy the buffer, legally initialize the string to something unique before changing it.

Of course, allocating a vector here is silly. Using std::wstring here is not wise also. It's better to use a char array to call the winapi. construct a wstring when returning value.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!