std :: string :: operator []的结果地址是否指向可写的,以null结尾的缓冲区?

时间:2012-03-15 21:27:49

标签: c++ stl operators stdstring c++03

我正在修改一个接受const char *并使用函数ProcessString的函数。 ProcessString是一个函数,它期望以null结尾的字符缓冲区作为char *。缓冲区中的字符可能会也可能不会被修改,如下面的函数签名所定义。为了“缩小差距”,我使用临时的std :: string:

void ProcessString( char* str );

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

我的主要问题是关于std :: string :: operator []的保证以及上面& temp [0]返回的地址是否是一个可用的,以null结尾的缓冲区作为char *。其次,第二,有更好的方法吗?

我正在使用C ++ 03。

3 个答案:

答案 0 :(得分:5)

在C ++ 11中只有明确定义的行为;在以前的标准中,std::string并不保证其内部缓冲区的连续存储。

然而,尽管该代码在C ++ 11中完全没问题,但更惯用的方法是使用std:vector<char>,这保证了自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
}

答案 1 :(得分:1)

我创建了一个小班来面对这类问题,我已经实现了RAII习语。

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_; }
};

您可以将其用作:

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

我已经调用了DeepString类,因为它正在创建现有字符串的深层唯一副本(DeepString不可复制)。

答案 2 :(得分:0)

如果您需要从const char*转到char *,为什么不使用strdup,然后在ProcessString完成后释放缓冲区?

通过std::string对我来说似乎没用。