避けられなかった穴--stringの中のc_strトラップ


string.c_strは、現在の文字列の先頭文字アドレスを返すBorlandパッケージのStringクラスの関数です.
c_str関数の戻り値はconst char*であり、char*に直接値を割り当てることはできないので、対応する操作変換が必要です.
#include   
#include   
int main() {  
    std::string s = "Chelse";  
    const char *str = s.c_str();  
    std::cout << str << std::endl;  
    s[1] = 'm';  
    std::cout << str << std::endl;  

    return 0;  
} 

最初の出力はもちろんChelseです.2番目の出力はChelseですか、それともCmelseですか.答えはCmelseです.const char*の値は定数ですね.どうして値を変えることができますか.これは多くの人が出会った穴で、面接の时にあなたは順調に答えるかもしれませんが、実際の工事では、穴に落ちて、抜け出せません.const char*,char const*,char*constの違いは何ですか?古いconst char*はchar const*と等価であり、文字定数を指すポインタ、すなわちポインタは指向を変えることができるが、その指向する内容は変えることができないことを指す.char*constとは逆に、定数ポインタを指します.つまり、ポインタは変更できませんが、ポインタが指す内容は変更できます.したがって,ここのconst char*が指すコンテンツ本クラスは変更できない.
では、ここはどうして変わったのでしょうか.これはstrというconst char*のライフサイクルとstringクラスの実現と関係があり、stringのc_str()が返すポインタはstringによって管理されるため、そのライフサイクルはstringオブジェクトのライフサイクルであり、stringクラスの実装は実際にchar*のポインタをカプセル化し、c_str()はポインタの参照を直接返すため、stringオブジェクトの変更は実行済みのc_に直接影響します.str()が返すポインタ参照.
公式の言い方を見てみましょう.
const charT* c_str() const;
Returns: A pointer to the initial element of an array of length size() + 1 whose first size() elements equal the corresponding elements of the string controlled by *this and whose last element is a null character specified by charT().
Requires: The program shall not alter any of the values stored in the array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a non-const member function of the class basic_string that designates the same object as this.

簡単に言えば、std::stringの非constメンバー関数を呼び出した後、c_str()の戻り値は信頼できません.