2012-01-16 25 views
0

私はこの小さなプログラムを持っています。std :: stringの奇妙な振る舞い

#include <iostream> 
#include <string> 
int main() 
{ 
    std::string st = ('='+"10"); 
    std::cout<<st<<"-"<<st.c_str(); 
    return 0;  
} 

実行しないとどのような出力が期待できますか?

私が取得しています:ブースト::精神ライブラリを使用して、C-文字列として周りにその出力を通過させながら-

は、私は、このような問題に実行しています。

何か不足していますか?私はgcc 4.6.1(ubuntu 10.10)を使用しています。

+1

コンパイラによって隣接する文字列リテラルが結合されることに注意してください。 '" = "" 10 "' '= 10" '(C++ 03、§2.13.4-3)。 – outis

答えて

3

この:

'=' + "10" 

は、おそらく何を期待しません。連結するのではなく、 "="の "ASCII"値をリテラル文字列 "10"へのポインタに "加算"する(算術的に)。これはバッファオーバーランであり、未定義の動作を引き起こす。

あなたがvalgrindの下でプログラムを実行すると、これについて不満を感じるでしょう。

代わりに、試してみてください。

std::string st = "="; 
st += "10"; 
+0

それは奇妙です!私は 'st + =" 10 "'が 'st = st +" 10として展開すると考えました。 – Dilawar

+3

@Dilawar: ''=''は文字であり文字列ではありません。また、c-stringを追加しても連結されません。したがって、ジョンの '+ ='の使用。 – outis

+0

あなたが正しいです、それらの2つのものは同等です。しかし、 "="ではなく "="を書いたことに注意してください.Cの文字列リテラル "10"をstd :: stringに追加しましたが、charに追加しました。 –

1

ではなく、試してみてください。

#include <iostream> 
#include <string> 
int main() 
{ 
    std::string st = ('='+std::string("10")); 
    std::cout<<st<<"-"<<st.c_str(); 
    return 0; 
} 

"10"const char*(ポインタ)です。これを追加すると、標準の整数演算を使用してポインタをインクリメントし、文字列を連結しません。

+0

私はコンパイラが警告を発するべきだと思います。私は-Wallでコンパイルしていました。 – Dilawar

+0

警告の理由はなく、ポインタをインクリメントするのはC/C++の一般的なプラクティスであり、それ自体で有効です。問題は、無効なアドレスを作成し、それをコンパイラーが知る方法がない文字列コンストラクターに渡すことです。 –

+0

@TimGee:公平であるために、コンパイラは '=' + "10"(文字列の長さ以上の文字列リテラルへのポインタをインクリメントする)について確実に警告することができます。コンパイラがまだそれをしていないのであれば、私は驚くことはありませんが、絶対に可能です。 –