1

プログラム #1:

#include<stdio.h>
#include<stdlib.h>
char *getString()
{
   char str[] = "GfG";
   printf("%s \n", str); 
   return str;
}    
int main()
{
    printf("%s", getString()); 
    return 0;
}

出力:

GfG
GfG

プログラム #2:

#include<stdio.h>
#include<stdlib.h>
char *getString()
{
    char str[] = "GfG";
    return str;
}    
int main()
{
    printf("%s", getString()); 
    return 0;
}

出力:

(ゴミの価値)

printfステートメントの出力のみが異なるため、理由を説明してください。正確な説明は何ですか?

4

6 に答える 6

10

どちらのプログラムも未定義の動作を示すためです。

getString関数が返されると、配列strオブジェクトは破棄され、有効期間後にアクセスしようとすると未定義の動作になります。

文字列リテラルには静的な保存期間があり、その有効期間はプログラムの全期間であるため、文字列リテラルを使用してプログラムを修正できます。

char *getString(void)
{
    char *str = "GfG";
    return str;
} 
于 2013-08-24T09:09:20.900 に答える
3
char str[] = "GfG";

自動変数を宣言します。( function ) で宣言されたスコープ内で this にアクセスすることのみが有効ですgetString。他の場所で使用しようとすると、未定義の動作が発生します。最初のバージョンが機能しているように見えたのは不運でした。

getString戻るときに、格納に使用されたスタック領域strが再利用される場合があります。これが発生すると、バイトが見つかるかクラッシュprintfするまで、メモリをさらに読み取ることになります。'\0'

于 2013-08-24T09:09:46.883 に答える
1

でメモリを割り当てるか、 でmalloc試す必要がありますstatic

于 2013-08-24T09:13:07.963 に答える
1

C では配列は値渡しではなく、アドレス渡しであることを覚えておいてください。strは で定義されているためgetstring()、制御が に戻った後は、main()その特定のアドレスにアクセスすることはできません。たまたまアドレスにアクセスした場合、結果は予測できません。C コンパイラは、プログラム内の不正なメモリ アクセス要求をチェックしないことに注意してください。

于 2013-08-24T09:22:41.613 に答える
1

ローカル変数char str[] = "GfG";のスコープは関数に限定されます。したがって、関数スコープでそれを印刷しようとすると、機能します。しかし、その関数の外からそれにアクセスしようとすると、undefined behavior.

#include<stdio.h>
#include<stdlib.h>
char *getString()
{
    char str[] = "GfG"; // Local variable, so once you try to return that it is undefined
    return str;
}    
int main()
{
    printf("%s", getString()); 
    return 0;
}

以下のリンクをたどると、さらに例が得られます。 この関数がメインで呼び出されると、ローカル変数はメモリから削除されますか

于 2013-08-24T09:24:32.240 に答える
0

どちらの場合も、char str[] = "GfG";最初の関数内でスタックに置かれます。それへのポインタを返します。呼び出し元はそれを使用して に渡そうとしますprintf()が、その間に「古い」スタックの内容は既に上書きされています。

それらの間に違いがあり、最初のものは古いコンテンツを少し長く保持する可能性がありますが、それに対する保証はなく、したがって未定義の動作です.

于 2013-08-24T09:22:41.810 に答える