Is string :: c_str () allowed to allocate anything on the heap?

If I need to get an N60-complete char array from std::string in a situation where I need to be sure that nothing will be allocated, can c_str be used for this? For example, if I am inside a destructor and I want to copy some data from string to a pre-allocated buffer of a fixed size, can I use c_str and be sure that it will not throw anything?

+11
source share
4 answers

The standard states that calling c_str() may invalidate references, pointers, and interpreters related to string elements, which implies that resolution is allowed (21.3 / 5 "Basic_string class template").

You can simply call string::copy() to get your copy (you will need to add a null terminator yourself if you need it).

+6
source

No, the standard does not provide such a guarantee. The only guarantee in the C ++ standard is that the return value points to a char array with the same contents as std::string , plus nul-terminator.

Thus, it would be standard-compliant for the implementation to maintain its internal representation in a way different from the C-string, and to highlight the C-string on the fly when you call c_str , although I'm pretty sure that the widely used STL implementation on doesn't really do that.

Now, with regard to C ++ 0x, I heard (although now I find it difficult to find documentation for this) that one of the changes will be the requirement that std::string work continuous storage (a similar requirement already exists for std::vector ) . Thus, in this case, you can access the range from &str[0] to &str[0]+str.length()-1 , as if it were a C-string without nul-terminator.

+6
source

The standard does not say this:

21.3.6 [lib.strings.ops]

const charT * c_str () const; 1 Returns: a pointer to the initial element of an array of length size () + 1, whose elements of the first size () equal the corresponding elements to a string controlled by * this and whose last element is the null character specified by charT ().

2 Required: the program must not modify any of the values ​​stored in the array. Also, the program will not consider the return value as a valid pointer after any subsequent call to a non-constant member function of the basic_string class, which designates the same object as this.

Can. However, Iv'e never saw any implementation that does.

If this bothers you, you might want to use vector<char> instead of string and do something like:

 vector<char> chars; // ... char* my_str = &chars[0]; 

The trick here is to know when and how to deal with the need for '\0' -terminated strings.

+2
source

The standard, but clearly indicates that a string can allocate memory when calling c_str . In particular, he says (Β§21.3 / 5):

References, pointers, and iterators related to the elements of the basic_string sequence can be invalidated by the following uses of this basic_string object:
[...]
- Calling the functions () and c_str () of the member functions.

It gives permission for pointers, references, and iterators to be specifically invalidated to allow the implementation to reassign the memory used to store the string when c_str called.

+1
source

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


All Articles