web-dev-qa-db-ja.com

Cでローカル変数のアドレスを返す

次の2つの機能があるとします。

1

int * foo()
{
  int b=8;
  int * temp=&b;
  return temp;
}

2

int * foo()
{
   int b=8;
   return &b;
}

最初の警告は表示されません(たとえば、関数はローカル変数のアドレスを返します)が、bがスタックから消え、未定義のメモリへのポインタが残ります。

では、一時値のアドレスを返すことに注意する必要があるのはいつですか?

13
mary

最初のスニペットで警告が表示されない理由は、(コンパイラーの観点から)ローカル変数にアドレスを返さないためです。

int * tempの値を返しています。この変数にローカル変数のアドレスである値が含まれている可能性がありますが(この例では含まれています)、コンパイラーはコード実行スタックを上って、これが当てはまるかどうかを確認しません。

コンパイラーが前者について警告していなくても、両方のスニペットは等しく悪いです。このアプローチは使用しないでください。


アドレスをローカル変数に返すときは常に注意する必要があります。原則として、あなたは決してすべきではないと言うことができます。

static変数はまったく別のケースですが、これについては このスレッド で説明しています。

18

ローカル変数を返すことができます。mallocによって動的に割り当てられた場合は、そのようなポインタを返すことができます。その場合、変数の格納に使用されるメモリはスタック上にありますが、ヒープ上にあり、後でクリアまたは再利用されません。自動ローカル変数(mallocなしで作成)の場合に発生する関数を終了しますか?

1
user989583

どちらの例も同じように正しくありません。私の推測では、コンパイラは危険を認識していないため、アドレスを一時変数に格納するときに警告を発行しません。

0
Lindydancer

この質問は、おそらくStackOで最も議論されている質問の1つです。以下は、StackOの同様のスレッドからの2つの返信で、興味深いと思いました。おそらく、間違った(未定義の動作)が非常にスリムになる可能性があるにもかかわらず、ローカル変数を参照解除するというこの悪い習慣をやめさせました。

ここに簡単な答えがあります

私は特にこの返信が好きでした。

これは、この悪い習慣が実際のハードウェアの損傷を引き起こした例です

0
Abhinav