質問: ft_strrev(str); printf("%s\n", str); return 0; } ```
回答: 問題あります。 言語仕様の言葉で説明します。 オブジェクトは種類ごとの生存期間 (lifetime) を定める記憶域期間 (storage duration) を持ち、質問中のプログラムにある配列 `tmp` は自動記憶域期間 (automatic storage duration) に分類されます。 自動記憶域期間を持つオブジェクトはそれに関連付けられたブロックの終わりまでが寿命です。 `tmp` の場合は関数 `ft_strrev` の終わりが寿命であり、寿命を終えたオブジェクトにアクセスした場合の結果は未定義となります。 JISX3010:2003 (いわゆる C99 に相当) の 6.2.4 から引用します。 > > オブジェクトの**生存期間** (lifetime) とは、オブジェクトに対して記憶域の確保が保証されている、プログラム実行の一部分をいう。 オブジェクトは、生存期間を通じて存在し、一定のアドレスをもち、最後に格納された値を保持する。 オブジェクトを生存期間の外部で参照したときの動作は未定義とする。 ポインタの値は、そのポインタが指すオブジェクトが生存期間の最後に到達すると、不定になる。 > > > C における「未定義の動作」というのは「その状況を無視して予測不可能な結果を返しても良い」ということを意味し、元の値の残骸が残っていることもあればデタラメな値かもしれず、あるいはクラッシュしても仕様通りです。 要するに未定義とされていることは実質的にしてはいけないことであると考えて良いです。 `tmp` の宣言に `static` を付けて静的記憶域期間にすれば一応は未定義ではなくなりますが、一般的にはあまりよくはないスタイルです。 episteme さんが提示するように元の配列を書き換える方法か、あるいは書き込み先の配列も呼び出し側で用意して与える方法が普通は望ましいでしょう。