1. 程式人生 > >沒有躲過的坑--string中的c_str()陷阱

沒有躲過的坑--string中的c_str()陷阱

string.c_str是Borland封裝的String類中的一個函式,它返回當前字串的首字元地址。

c_str函式的返回值是const char*的,不能直接賦值給char*,所以就需要我們進行相應的操作轉化。

#include <iostream>  
#include <string>  
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;
第二個輸出呢: 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() 的返回值就不可靠了。