ポインタの学習中、検証のため以下のコードを実行したところ、セグフォが発生しました。
これは、一時バッファを用意せずにリテラルプールにある文字列へ上書きする結果、'\0'の分により1つずれてしまうという例を検証するためのものです。
char* string1= "abcd"; char* string2= "efgh"; strcat(string1, string2); printf("%s\n", string1); // 望む結果 => abcdefgh printf("%s\n", string2); // 望む結果 => fgh (開始アドレスのずれにより)
中間バッファを用意した場合には当然起きません。
連結もリテラルを変更しようとする動作として検知され、エラーを出しているのでしょうか。
または、教科書ではエラーは出ていないようでしたので実行環境によるものでしょうか。
よろしくお願いいたします。
> 連結もリテラルを変更しようとする動作として検知され、エラーを出しているのでしょうか。
strcat は第1引数の文字列の後ろに第2引数の文字列を連結するという仕様ですから、"変更しようとする" しか無いと思います。
ありがとうございます。
確かにおっしゃる通りでした。
しかしなぜ教科書ではエラーになると出ていなかったのか...
あまり深く考えないようにします。<(_ _)>
「セグメンテーションフォルトにならなければならない」という仕様は無いと思いますので、最終的には環境依存ではあると思います。
個々に一々「環境依存です」と注釈を入れるのもくどいと思いますので、「以下略」状態なのかもしれませんね。
そもそもの話として、
> '\0'の分により1つずれてしまう
という現象が一般に期待できるものではないような。
C言語のレベルでは
char* string1= "abcd";
char* string2= "efgh";
がメモリ上にどう配置されるかについての縛りはないですから。
その「教科書」は、「コンパイラを作ってみよう」とかいうお題で、その特定のコンパイラの挙動の話だったりしませんか?
jimbe様
ありがとうございます。そこまで重要な雰囲気を出しているセクションではないようなので筆者もそのような意図だったのかもしれません。いずれにしてもしてはいけないことの一つとして頭に入れておきます。
thkana様
よく文章を見てみますと、"直後に配置することとする"という文脈であり、このことからもしできたとするならば的なニュアンスがありました。
確かにおっしゃる通り連続される保証はない領域の話なので、理解を促進するための一例だったのだと理解しました。ありがとうございます。ちなみにポインタの書籍です。
以下のようにしますと、望む結果が得られました。
配列を用いることで、スタックにできたコピーいじるためセグフォが起きないようです。
---------------------------------------------------------
char string1[] = "abcd"; // char string1[30] とすると当然上書きは行われない。
char string2[] = "efgh";
strcat(string1, string2);
printf("%s\n", string1); // abcdefgh
printf("%s\n", string2); // fgh

回答2件
あなたの回答
tips
プレビュー