0

以下の2つの関数に違いはありますか?どちらの場合も返されるローカル変数のアドレスではありませんが、f1() fnを使用すると正しい値4が返されますが、f2()は返されません。また、3番目のケースでは、文字列定数がスタックに格納されていないため、ポインターを返すと正常に機能するということは正しいです。また、文字列定数はどこに保存されていますか?

int* f1()
{
  int* a=(int*)4;
  return a;
}

int* f2()
{
  int a=4;
  return &a;
}

char* f3()
{
  char* p="abcd";
  return p;
}
4

3 に答える 3

6

それらすべてには違いがあります。

  1. 1 つ目は、値 4 の を返します。int *値 4 の変数ではなく、アドレス 4 を指していることに注意してください。
  2. 2 番目は 4 を保持する変数へのポインターを返しますが、実際には、このポインターは有効ではありません。既に返された関数のローカル変数を指しているためです。このポインターを使用すると、未定義の動作が発生します。
  3. 3 番目は (定義により) char へのポインターを返しますが、実際にはこれは (実装により) 文字列リテラルへのポインターです。これに関する問題は、関数が returnchar *ではなくconst char *であるため、戻りバッファーを変更しようとする可能性があり、これも未定義の動作になることです。
于 2012-05-07T11:36:07.887 に答える
1
  • f1値 4 をアドレスにキャストし、実際にはメモリ内のどこかを指します。
  • f2ローカル変数のアドレスを返します。このポインターを逆参照すると、未定義の動作になります。
  • f3文字列リテラルへのポインタです。文字列リテラルの有効期間はプログラムの有効期間 (静的ストレージ期間)と同じであるため、これは有効なポインターです。このリテラルが格納される正確な場所は、実装によって定義されます。文字列リテラルの内容の操作は未定義の動作です。
于 2012-05-07T11:37:32.420 に答える
0
  • f1アドレスを明示的に指定し、その4アドレスの値ではなく同じ値を返しました。
  • ローカル変数はスタックに割り当てられるため、返されたf2場所では、メモリ内のそのアドレスに存在する では&aなく、スタック上のアドレスが返さ4れます。このアドレスを逆参照すると、関数がスタックからフラッシュされるため、未定義の動作が発生します。
  • 文字列リテラルは読み取り専用データ セクションに割り当てられます。

    char arr[]="abcd";char *ptr="abcd";

    1 つ目は文字配列で、スタックに割り当てられます。2 つ目は、読み取り専用データ セクションに割り当てられる文字列リテラル (ポインターではなくリテラル) へのポインターです。

PS: ここでは GCC/x86 を想定しています。

于 2012-05-07T11:55:12.490 に答える