2

しばらくの間、私を悩ませていたものがあります。それに対する答えが必要です。

char *p = "hello world";
p="wazzup";
p="Hey";

ここで、文字列を指すポインターを宣言します (つまり、ポインターを使用して文字列を作成しました)。

char配列文字列を使用した場合、通常は得られない奇妙な結果が得られました

cout <<p<< endl; //"Hey" Gets printer
cout <<p+8<< endl; // I kept adding numbers till "wazzup" got printed
cout <<p+29<< endl; // No matter how much I increment, I cant print "Hello World"

だから私の質問は:

char ポインターが指している値を変更すると。しますか

  • char 配列の場合と同様に、元のデータを上書きします。

  • または、メモリ内の直前に新しい文字列を作成し、それを指します。

  • または、古い文字列の先頭に新しい文字列を追加しますか(nullを含む);

  • それとも、メモリ内の新しい場所に新しい文字列を作成し、たまたま「wazzup」を印刷できましたか

4

7 に答える 7

4

上記のオプションのいずれも行いません。ポインターの値を変更しても、ポインターが指すメモリー内のアドレスが変更されるだけです。への割り当てのそれぞれのケースで、pメモリに格納されている (異なる) 文字列リテラルの最初の文字を指すように設定されています。

次のような文字列リテラルの末尾を超えるポインタを使用する動作

cout <<p+8<< endl

未定義です。これが、ポインターの使用が危険を伴う理由です。

表示されている動作は実装に依存します。コンパイラは文字列リテラルを隣接してメモリに格納するため、1 つの実行の終わりから別の実行に移ります。別のコンパイラでコンパイルすると、プログラムが同様にクラッシュする可能性があります。

于 2012-08-11T14:09:20.993 に答える
2

ポインターに追加することで、アドレス値が増加します...したがって、印刷中に、そのメモリ位置に保存されている値が印刷され、他には何も印刷されません...

印刷できれば

"hello world"
"wazzup"

それはまぐれです:)

于 2012-08-11T14:10:54.947 に答える
1

これら 3 つすべてが文字列リテラル定数です。これらは実行可能ファイルのバイナリに直接表示され、 を割り当てるたびにp、メモリ内のこれらの場所を指します。それらは完全に別個のメモリです。別のものに再割り当てpしても、文字列データは変更されません。

于 2012-08-11T14:09:40.163 に答える
1

ポインターを割り当てるたびに、ポインターを別の何かに向けているだけです。したがって、データがどこにも上書きされる可能性はありません。内部で何が起こるかは実装に依存するため、表示されるのはまったくの偶然です。これを行う場合:

cout <<p+8<< endl;

文字列リテラルの範囲を超えて、未定義の動作を呼び出しています。

于 2012-08-11T14:09:43.753 に答える
1

char ポインターが指している値を変更すると。しますか

-char 配列の場合と同様に、元のデータを上書きします。いいえ、アドレス空間のデータ部分には、「Hello World」、「wazzup」、「Hey」の 3 つの文字列がすべて含まれています。ポインターを変更すると、 p の値が上記のいずれかの文字列の開始アドレスに変更されるだけです。ポインターが指しているアドレスを変更することと、ポインターが指している値を変更することは、2 つの異なることです。

-または、メモリ内の直前に新しい文字列を作成し、それを指します。コンパイラは、実行時ではなくコンパイル時に文字列 (文字バイト) を作成します。

-または、メモリ内の新しい場所に新しい文字列を作成し、偶然に「wazzup」を印刷できたのでしょうか。上記の回答がこの質問をカバーしていると思います。

- または、古い文字列の先頭に新しい文字列を追加しますか (null を含む)。コンパイラの仕様に依存します。

于 2012-08-11T14:11:11.943 に答える
1

3 つの文字列が同じメモリ位置に配置されていません。この 3 つのメモリは、シーケンシャルまたは異なる場所である可能性があります。コンパイラが 3 つのメモリを割り当てる場合、+/- 値を使用してそれを見つけます。コンパイラに完全に依存します。c では、任意のメモリ位置を準備できるため、+/- ポインター p のときにエラーが発生することはありません。

于 2012-08-11T14:12:01.420 に答える
0

これら 3 つは同じ文字列ではないため、メモリの異なる部分に配置されます。64 バイト アラインで分離できると思います。p + 64を試してください:)

コンパイラがサポートしている場合にのみ、同じ文字列のみがメモリの同じ場所に配置されます。

p+64 で「wazzup」、p+128 で「hey」の可能性があります (VC++ 2010 Express を使用し、pentium-m cpu を使用し、windows xp sp-3 を使用している場合)。

cout <<*(p+64)<< endl;
cout <<*(p+128)<< endl;
于 2012-08-11T14:06:54.237 に答える