ローカル変数のアドレスを返すと、その変数は有効範囲外になり、その変数で使用されるメモリの場所は他の目的で再利用できます。このようなポインタの逆参照を試みると、undefined behaviorが呼び出されます。
未定義のビヘイビアを呼び出すと、何かが起こる可能性があります。コードがクラッシュしたり、予期しない結果が表示されたり、正しく動作するように見えることがあります。余分な未使用変数や追加/削除されたprintf
の追加など、コードに一見無関係な変更を加えると、その動作が変更される可能性があります。 はおそらくは何が起こっているのかについては
は、あなたがメインでresult
を移入時に、他の関数がまだ呼び出されていないので、getINT
にy
が使用するスタック領域は、まだ上書きされていません。次のステートメントでは、そのポインタを逆参照してy
の値を取得します。これは、関数が呼び出される前に実行されるため、y
の値はまだ上書きされていないため、値を取得できます。
ptr
の場合は、そのポインタを直接printf
に渡します。 printf
を呼び出した行は、スタックに書き込みを行い、以前にstr
が占有していたメモリをgetARRAY
に上書きします。
*result
を印刷する前にprintf("hello\n");
を追加する場合は、その値として10
を印刷しない可能性があります。同様に、ptr
が指す文字列をループ内のローカル変数main
(他の関数を呼び出さずに)にコピーした場合、おそらく文字列Hai
が復元されます。
この場合も、この動作に依存することはできません。いくつかのコンパイラは、関数が復帰した後にスタック上にあったものをクリアすることを選ぶかもしれません。同様に、最適化レベルを変更すると、関数がインライン化され、スタックが変更されなくなる可能性があります。これはすべての未定義の動作の一部です。
はどちらも定義されていない動作なので、「作業中」機能に頼るべきではありません。 – mch
偶然の問題。 –