Does the address of the result of std::string::operator[] point to a writable, nul-terminated buffer?

雨燕双飞 提交于 2019-12-24 02:47:10

问题


I am modifying a function that accepts a const char* and uses a function, ProcessString. ProcessString is a function that expects a null-terminated character buffer as a char*. The characters in the buffer may or may not be modified, as defined by the function signature below. To "bridge the gap", I am using a temporary std::string:

void ProcessString( char* str );

void SomeFunction( const char* str )
{
  string temp(str);
  ProcessString( &temp[0] );
}

My primary question is about the guarantees of std::string::operator[] and whether the address returned by the &temp[0] above is a usable, null-terminated buffer as a char*. Secondly, and very much secondly, is there a better way to do this?

I am using C++03.


回答1:


That only has well-defined behavior in C++11; in previous standards, std::string did not guarantee contiguous storage for its internal buffer.

However while that code is completely fine in C++11, the more idiomatic approach is to use std:vector<char>, which has guaranteed contiguous storage since C++03:

void ProcessString(char* str);

void SomeFunction(char const* str)
{
    // + 1 for terminating NUL
    std::vector<char> temp(str, str + std::strlen(str) + 1);
    ProcessString(&temp[0]); // or temp.data() in C++11
}



回答2:


I have created a small class to face this kind of problem, I have implemented the RAII idiom.

class DeepString
{
        DeepString(const DeepString& other);
        DeepString& operator=(const DeepString& other);
        char* internal_; 

    public:
        explicit DeepString( const string& toCopy): 
            internal_(new char[toCopy.size()+1]) 
        {
            strcpy(internal_,toCopy.c_str());
        }
        ~DeepString() { delete[] internal_; }
        char* str() const { return internal_; }
        const char* c_str()  const { return internal_; }
};

And you can use it as:

void aFunctionAPI(char* input);

//  other stuff

aFunctionAPI("Foo"); //this call is not safe. if the function modified the 
                     //literal string the program will crash
std::string myFoo("Foo");
aFunctionAPI(myFoo.c_str()); //this is not compiling
aFunctionAPI(const_cast<char*>(myFoo.c_str())); //this is not safe std::string 
                                                //implement reference counting and 
                                                //it may change the value of other
                                                //strings as well.
DeepString myDeepFoo(myFoo);
aFunctionAPI(myFoo.str()); //this is fine

I have called the class DeepString because it is creating a deep and unique copy (the DeepString is not copyable) of an existing string.




回答3:


If you need to go from a const char* to a char *, why not use strdup, and then free the buffer when ProcessString is done?

Going through std::string seems unnecessary to me.



来源:https://stackoverflow.com/questions/9728450/does-the-address-of-the-result-of-stdstringoperator-point-to-a-writable-n

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