掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28698

ポインタ先の内容の書き換え方について
投稿者---kim(2006/11/03 22:10:28)


ポインタについては大体理解できたのですが、下記のプログラムで
コンパイラ:VC++6.0

char *p = "abcde";
*(p+2) = 'a';

ポインタ変数で直接どこかのアドレスに書き込んだ場合、
その部分の一部を変更したいのですがどうしてもうまくいきません。
添え字をつけてあげると動作するのですがこの方法のみ動作せず理解もできなくて悩んだ末投稿しました。
どこがいけないのか、どうすれば内容を書きかえれるのかご教授願います。



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ポインタ先の内容の書き換え方について 28699 DD. 2006/11/03 22:41:38
<子記事> Re:ポインタ先の内容の書き換え方について 28700 気分屋 2006/11/03 22:48:47


No.28699

Re:ポインタ先の内容の書き換え方について
投稿者---DD.(2006/11/03 22:41:38)


>char *p = "abcde";
>*(p+2) = 'a';
>この方法のみ動作せず理解もできなくて悩んだ末投稿しました。
特に問題ないように見受けられます。

どのようなエラーが出るのか明記されたほうがよいと思います。


この投稿にコメントする

削除パスワード

No.28700

Re:ポインタ先の内容の書き換え方について
投稿者---気分屋(2006/11/03 22:48:47)


>char *p = "abcde";
上記の"abcde"は読み取り専用領域になっています。
そこを書き換えようとしたからエラーが出ただけです。

>char p[] = "abcde";
これで解決。



この投稿にコメントする

削除パスワード

No.28701

Re:ポインタ先の内容の書き換え方について
投稿者---DD.(2006/11/03 23:02:20)


>>char *p = "abcde";
>上記の"abcde"は読み取り専用領域になっています。
なるほど。横からで申し訳ないのですが、質問させて下さい。

VC8 で試してみましたが、特に怒られることなく正常に動いているように見られました。

VC6では試していませんが、コンパイラによりこの動作は変わるのでしょうか?
でもCの規格として定められた内容であるならばコンパイラ依存なわけはないですよね。。。
(規格書読んでないのですが)


この投稿にコメントする

削除パスワード

No.28702

Re:ポインタ先の内容の書き換え方について
投稿者---kim(2006/11/03 23:20:03)


>char p[] = "abcde";
>これで解決。
これでも出来ることを知っていて質問していました。
でも、私的にはなぜあのソースコードがエラーがでるのかがきになって
仕方なくて投稿させていただきました。

コンパイラではエラーは出ないのですが実際実行してDOS窓が開いてその
コードのときにWindowsのエラーが出ます。
コンパイルやビルド時にはエラーは発生しません。
しかもポインタ指定の文字列で作り出した領域にポインタを利用してアクセスしようとしたときのみ同じ現象が発生します。
ソースコードとしてはまったく問題なしでしょうか?

>VC8 で試してみましたが、特に怒られることなく正常に動いているように見られました。
VC8では正常に動作するのですか…
VC6のコンパイラのバグなのでしょうか…。
開発環境はVC6を入れて特に設定をいじっておらず、インストール時のデフォルトのままです。


この投稿にコメントする

削除パスワード

No.28703

Re:ポインタ先の内容の書き換え方について
投稿者---YuO(2006/11/03 23:25:51)


>>上記の"abcde"は読み取り専用領域になっています。
>VC8 で試してみましたが、特に怒られることなく正常に動いているように見られました。
>VC6では試していませんが、コンパイラによりこの動作は変わるのでしょうか?

規格上,文字列リテラルを変更しようと試みることは未定義動作 (ISO/IEC 9899:1999 6.4.5 String literals) とされています。
>If the program attempts to modify such an array, the behavior is undefined.
なので,「読み取り専用領域」というのは実装依存の話です。
「何事もないように動作する」可能性もあります。

ただし,コンパイラは変更が無いことを前提に作ることができますから,同一の文字列リテラルをまとめる実装があった場合,片方の文字列を変更するともう一方の文字列が変更される可能性もあります。



この投稿にコメントする

削除パスワード

No.28704

Re:ポインタ先の内容の書き換え方について
投稿者---DD.(2006/11/03 23:31:35)


YuOさんありがとうございます。

>規格上,文字列リテラルを変更しようと試みることは未定義動作 (ISO/IEC 9899:1999 6.4.5 String literals) とされています。
>なので,「読み取り専用領域」というのは実装依存の話です。
納得です。ありがとうございました。


この投稿にコメントする

削除パスワード

No.28705

Re:ポインタ先の内容の書き換え方について
投稿者---kim(2006/11/03 23:57:12)


>YuOさんありがとうございます。
>
>>規格上,文字列リテラルを変更しようと試みることは未定義動作 (ISO/IEC 9899:1999 6.4.5 String literals) とされています。
>>なので,「読み取り専用領域」というのは実装依存の話です。
>納得です。ありがとうございました。

初心者の私には完全に理解できませんが、この行動については
読み取り専用領域の為にそこに無理やり変更しようとする行為は
とても危険な行為で実行時にエラーが出る可能性が高い現象という認識で
よろしいでしょうか?
あのような造り方の場合はconstで指定したと過程した状態で使わないといけないということですね?(危険なため)

なんとなく理解が出来ました。
素直に[] = で今後使うことにします。
ご教授いただいた方ありがとうございました。


この投稿にコメントする

削除パスワード

No.28707

Re:ポインタ先の内容の書き換え方について
投稿者---気分屋(2006/11/04 00:46:21)


>初心者の私には完全に理解できませんが、この行動については
>読み取り専用領域の為にそこに無理やり変更しようとする行為は
>とても危険な行為で実行時にエラーが出る可能性が高い現象という認識で
>よろしいでしょうか?
Cとして未定義になっている処理を行ことがまずいということです。
私の書いた読み取り専用領域という言い方がよろしくなかったですね。

Cの未定義については以下のページが参考になると思います。
初級C言語Q&A



この投稿にコメントする

削除パスワード

No.28708

Re:ポインタ先の内容の書き換え方について
投稿者---RAPT(2006/11/04 00:48:08)


危険といえば危険です。
char* で指定した先を変更しようとする行為の結果については「未定義」
とされているので、最悪HDDがフォーマットされてもおかしくないです。
# とはいえ、通常、そのようなことはありえませんが。


この投稿にコメントする

削除パスワード

No.28706

Re:ポインタ先の内容の書き換え方について
投稿者---気分屋(2006/11/04 00:35:29)


>規格上,文字列リテラルを変更しようと試みることは未定義動作 (ISO/IEC 9899:1999 6.4.5 String literals) とされています。
そうだったんですね。
勉強させさせていただきました。
ありがとうございます。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧