2012-01-03 23 views
4

私は以下のような何かを行うことができない理由私は文字列オブジェクトに書き込むことができますが、なぜ文字列リテラルに書き込むことができませんか?

*s1 = 'w'; // gives segmentation fault ...why??? 

は、私は以下のような何かを行う場合は、

string s1 = "hello"; 

ができ、以下のようなもの、

char *s1 = "Hello"; 

を定義した場合以下のようにしてください。

*s1 = 'w'; 
+0

[このCコードがセグメンテーションフォールトを引き起こすのはなぜですか?](http://stackoverflow.com/questions/1614723/why-is-this-c-code-cause-a-segmentation-fault) –

+1

http:// stackoverflow。com/questions/943191 –

+0

これらの質問は最初の部分を尋ねるだけであり、C++の文字列の大文字と小文字の違いを求めないため、重複していません。 – Mark

答えて

10

"Hello"はconst char []を作成するためです。これはconst char*に崩壊し、char*ではありません。 C++では、文字列リテラルは読み取り専用です。あなたはそのようなリテラルへのポインタを作成し、それに書き込もうとしています。 s1

しかし、あなたは

string s1 = "hello"; 

を行うときは、constの文字をコピー* "こんにちは"。に実施例1でs1点である差は「ハロー」読み取り専用及び第二の例では読み取り専用「ハロー」非const s1にコピーされ、あなたがコピーした文字列内の要素にアクセスすることを可能にしますあなたが彼らと一緒に望むことをやってください。問題を混同する

あなたが文字と同じことをしたい場合は*あなたはchar型のデータのためのスペースを割り当てる必要と

char hello[] = "hello"; // creates a char array big enough to hold "hello" 
hello[0] = 'w';   // writes to the 0th char in the array 
+2

'char hello [] =" hello ";'も有効です。 –

+0

@Fred、thanks、updated –

+2

"hello"の型はchar const *(またはあなたが主張する場合はconst char *)ではありませんがchar char [ (または、char *に代入されることを受け入れる)。 –

1

Helloは読み取り専用メモリに存在するためです。あなたの署名は、実際にあなたが変更可能なバッファをしたい場合は、char[]としてs1を宣言

const char* s1 = "Hello"; 

でなければなりません。 std::stringoperator []にオーバーロードされるため、インデックスに登録することができます(s1[index] = 'w')。

2

通常、文字列リテラルは読み取り専用データセグメントで割り当てられます。

+1

Trueですが、会話をC++で定義されている抽象マシンの範囲に制限することがより効果的です。文字列リテラルが定数データとして扱われることを確実にするためには、すでにそれが外れています。これを有用/安全な選択とする物理的な現実について話す必要はありません。特に、現実の精度は、世界中で使用されている広範な物理的実装全体にわたって、時間とともに変化する可能性があります。 –

0

それにハローコピー時間:

char s0[] = "Hello"; 
s0[0] = 'w'; 

これは完璧です有効です!もちろん、これは元の質問には答えないのでここで説明します。文字列リテラルは読み取り専用メモリに作成されます。つまり、その型はchar const[n]です。nは文字列のサイズ(文字列リテラルの場合はn == 6を含みますが、なぜこの型を使用してchar const*を初期化することができますか?下位互換性、それぞれ[古い] Cコードとの互換性:時間がconst言語でそれを作った、場所の多くはすでに文字列リテラルでchar*を初期化しました。この適切なコンパイラは、この虐待について警告する必要があります

関連する問題