2017-04-18 6 views
4

ローカル変数は、少なくとも関数内に存在します。しかし、ブロック外のブロックスコープ変数はどうなるのでしょうか?同じ機能ですが、そのアドレスを保持して使用できますか?このコードは有効ですか?C 'がローカルスタック変数を割り当て解除するとき?

#include <stdio.h> 

int main() 
{ 
    char *f; 
    if (1) 
    { 
     char q[] = "123"; 
     f = q; 
    } 

    printf ("%s\n", f); 
    return 0; 
} 
実際に

gcc -ansi -pedanticもvalgrindのそれに文句を言うでもないが、私はそれクロスプラットフォーム、クロスコンパイラ使用することができますか?私には見えませんが、どのツールでエラーが表示されるのですか?

P.S.結局私はstaticを使うべきですか?それは適切な解決策かもしれませんが、スレッドセーフなものではないようですね。

+3

ここで、重複は非常に良い答えではありません。問題は、別の関数から戻ってこない関数内の範囲についてです。同様に無効ですが、この質問の例が有効期限切れのスタックフレームへのポインタを単に戻すよりも無効な理由はさらに微妙です。 – Persixty

答えて

9

できません。自動保存期間を持つ変数の有効期間は、囲みブロックに設定されます。あなたが終わるのは、ぶら下がっている参照であり、それを使用することは未定義の動作です。

[C11 §6.2.4 ¶2]

オブジェクトの寿命は、ストレージがそれのために予約されることが保証される間、プログラムの実行の一部です。オブジェクトは存在し、一定のアドレスを持ち33)、そのライフタイムを通して最後に格納された値を保持する.34)オブジェクトがその存続期間外に参照された場合、その動作は未定義である。ポインターの値は、それが指し示すオブジェクト(または直前のもの)がその存続期間の終わりに達すると、不確定になります。可変長配列型を持たない(自動保管期間を持つ)ようなオブジェクトについて

[C11 §6.2.4 ¶6]

、その寿命は、それが実行されるまで関連付けられているブロックへのエントリから延びていますそのブロックの終わりは決して終わりません。

+1

私のマシンでこのコードをチェックしたところ、出力は "123"でした。それがUBだと言うと、PCはそのデータを置き換えて(それに応じて権限を変更することができます)、好きなものはどれですか? – CIsForCookies

+2

@CIsForCookies - 未定義の動作であると言うと、Cの標準では、一貫して正しいコードを生成するためのコンパイラや、正しいコードを作成する必要はありません。 – StoryTeller

+1

@CIsForCookies "123"がローカル変数としてスタックに置かれるため、これはUBです。スコープが終了すると、スタックポインタは、CPU時間の無駄になるので、未使用のスタックをクリアすることなくその位置を変更します。 "123"が(未使用の)このスタックを再利用する別の関数を呼び出すと、UBが表示されます。そのため、ローカル変数(およびポインタ)を初期化する必要があります。 – Rogus

関連する問題