Skip to content

Instantly share code, notes, and snippets.

@tos-kamiya
Created December 12, 2013 08:00
Show Gist options
  • Save tos-kamiya/7924621 to your computer and use it in GitHub Desktop.
Save tos-kamiya/7924621 to your computer and use it in GitHub Desktop.
ここに解答を記述してください。
【理由】
以下の2つの理由による。
・reallocは新しいヒープを確保する場合と元のヒープを拡張する場合の2通りの動作がある。
・10行目の代入分の実行で、左辺が先に評価されるか右辺が先に評価されるかは処理系によって異なる
(C言語の規格はどちらも許す)。
左辺が先に評価され、かつ、reallocが新しいヒープを確保する場合に、実行結果がret=0になる。
o 左辺が先に評価され、かつ、reallocが新しいヒープを確保する場合
9行目の実行により、spが指している(旧)ヒープの内容は0になる。
10行目の実行では、まず左辺を評価し、変数spが指している旧ヒープが代入先になる。
その後、右辺を評価し、func1が実行される。
func1の実行中にspはreallocが確保した新ヒープを指すように更新される。
新ヒープには、reallocの呼び出しにより旧ヒープの内容すなわち0が入っている。
func1から制御が戻ってきた後、先ほど確定した代入先すなわち旧ヒープに戻り値1が代入される。
結果、11行目の実行時点で、spが指す新ヒープには0が入っている。
o 右辺が先に評価される場合
10行目の実行では、まず関数func1が呼び出され、func1の実行中にspが更新されてから、
spが指すヒープに戻り値の1が代入がされる。
結果、(reallocの呼び出しにより新しいヒープが確保される・されないにかかわらず)
11行目の実行時点でspが指しているヒープには1が入っている。
o reallocが新しいヒープを確保しない場合
10行目の実行では、右辺の実行によりspが指すヒープ(のアドレス)は変化しないので、
いずれにせよspが指すヒープにfunc1の戻り値1が代入される。
結果、11行目の実行時点でspが指しているヒープには1が入っている。
【解決方法】
最も軽微な変更としては、
10行目の左辺と右辺を2つの文に分けて、実行順序を右辺→左辺に確定させる。
int v = func1();
*sp = v;
可能なら、func1の引数で明示的にspを渡すようにして、より意味を取りやすくする。
さらに可能なら、spを大域変数ではなくmainのローカル変数にする。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment