ページ 11

printfの有無で値が変わる

Posted: 2016年11月01日(火) 23:34
by サバ味噌
下記のプログラムはprintfでaのアドレスを表示させると、
mainでfの引数に入れた数字が出力され、表示させないと不定値が出力されます。
aのアドレスを表示させるとなぜ引数の値が出力されるのでしょうか?
メモリ解放はされないのでしょうか?

出力例
printfあり
----------------------------------------
0x7ffd72e66b74 = 2

printfなし
----------------------------------------
-753662152

ソース
----------------------------------------
#include <stdio.h>
int *f(int x){
int a = x;
printf("%p = ", &a); //ココの有無で値が変わる
return &a;
}

int main(void){
printf("%d", *f(2));
}

Re: printfの有無で値が変わる

Posted: 2016年11月01日(火) 23:39
by みけCAT
ソースコードを提示する際は、BBCodeを有効にした(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。
サバ味噌 さんが書きました:下記のプログラムはprintfでaのアドレスを表示させると、
mainでfの引数に入れた数字が出力され、表示させないと不定値が出力されます。
aのアドレスを表示させるとなぜ引数の値が出力されるのでしょうか?
まず言えることは、このコードはスコープを抜けて既に消滅した変数へのポインタをデリファレンスしているので、未定義動作を起こします。
その上で、おそらく最適化の影響で実行結果が変わっているのでしょう。
どうして今回たまたまこういう結果になったのかを調べるには、コンパイラにアセンブリ言語を出力させてどうなっているか見てみるといいかもしれません。
オフトピック
厳密には、void*型のデータを要求する%pにint*型のデータを渡すのも、型が違うので未定義動作です。

Re: printfの有無で値が変わる

Posted: 2016年11月02日(水) 00:31
by サバ味噌
初めて質問したので、勝手がわからずご迷惑をお掛けしてすみません。
次からは気をつけます。

最適化なんて意識したことがなかったので勉強になりました。
ありがとうございました。

Re: printfの有無で値が変わる

Posted: 2016年11月02日(水) 07:26
by あんどーなつ
サバ味噌 さんが書きました: #include <stdio.h>
int *f(int x){
int a = x;
printf("%p = ", &a); //ココの有無で値が変わる
return &a;
}

int main(void){
printf("%d", *f(2));
}
ソースコードの臭いところをかぎ分けることも重要です。
スタック変数のイメージを即席で作りましたので、参考にしていただければと思います。
(注意)実際とはだいぶ異なります。あくまで、イメージです。
001.png
001.png (10.96 KiB) 閲覧数: 3063 回