スタックとメモリ解放の話
Twitterで、とあるコードについて話題になっていたので、まとめてみる。
問題のコード
#include <stdio.h> int* func(){ int a = 114514; return &a; } int main(){ printf("%d\n", *func()); }
結論としては、動作は未定義である。環境によって挙動が変わる。 ということらしいが、実際にはどのような挙動をする可能性があるのだろうか。
様々な挙動
114514
と表示される
私が普段使用している環境だと、この挙動を示した。 「局所変数a
の領域がページアウトされていない」かつ、「printf()
の呼び出しの際、引数や局所変数で上書きされていない」場合にこの挙動を示す。Segmentation fault
wandbox(C++コンパイラ)で確認した挙動。「局所変数コンパイラがnull返すようにしてくれていたようです。Thanks, うさぎさんa
がページアウトされていた」場合にこの挙動を示す。別の値が表示される
「printf()
呼び出しの際に、引数や局所変数で上書きされた」場合に起こりうる。 未確認。
追記:gcc 4.9以前と5.1以降で変わるらしい。5.1以降だとnullを返すようになる。 d.hatena.ne.jp
感想的な
そもそも、CとかC++はコードの安全面はプログラマに任せているというような話を聞いた気がするし、 こんなコード書くなという話なんだけれど…
こういった、未定義のコードの挙動について考えてみるのって楽しい。もっと探ってみたい。