2
#include <stdio.h>
char* fun1()
{
  char *s="hello";
  return s;
} 
char* fun2()
{
  char s[6]="hello";
  return s;
}
main()
{
  char *str;
  str = fun1();
  printf("%s",str);//hello
  str = fun2();
  printf("%s",str);//garbage value
}

コードの出力は、hello とゴミです。fun1 と fun2 の両方の変数がそれぞれの関数に対してローカルであるにもかかわらず、出力がそのようになる理由を理解していません。両方の関数呼び出しはローカル変数のアドレスを返し、返されるアドレスには fun1 の場合には当てはまらないガベージ値が含まれている必要があります。 「こんにちは」を印刷しています。

4

2 に答える 2

6

2 番目のケースでは、オブジェクトは のスタック上にfun2存在するため、最初のケースでは固定領域に存在します。呼び出しがfun2終了すると、範囲外になります。つまり、終了します。

両方の関数呼び出しがローカル変数のアドレスを返す

のスタック上に実際にあるのfun1単なるポインターであり、コンテンツ自体ではありません。したがって、プログラムの最後まで存続することが保証されているものへのポインター、つまり文字列リテラルを返しています。

于 2013-02-27T11:29:36.163 に答える
0

2 番目の関数では、ローカル変数へのポインターを返しています。

fun2() の呼び出しが完了するとすぐに、s[6] に割り当てられたメモリが解放されるため、ポインタはメモリ内の無効な場所を指します。

次のようにコードを変更できます。

char* fun2(char *s)
{
    strcpy(s, "hello");
}

char str[6];
fun2(str);
printf("%s",str);

現在、str[6] 変数は fun2() の外部に割り当てられているため、この変数のメモリは fun2() の終了時に解放されません。


編集: 上記のコードは安全ではないことに注意してください。fun2() はメモリに書き込むバイト数をチェックしたり制御したりしないためです。

于 2013-02-27T11:31:41.250 に答える