2

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

void ProcessString( char* str );

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

我的主要问题是关于 std::string::operator[] 的保证以及上面 &temp[0] 返回的地址是否是一个可用的、以空值结尾的缓冲区作为 char*。其次,非常其次,有没有更好的方法来做到这一点?

我正在使用 C++03。

4

3 回答 3

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
}
于 2012-03-15T21:32:57.273 回答
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 不可复制)。

于 2012-03-15T21:34:34.850 回答
0

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

经历std::string对我来说似乎没有必要。

于 2012-03-15T21:31:39.107 回答