誤りがちな、古典的な質問:ノーリターンスタックメモリポインタのリターンポイント

前提条件:分類メモリ

:2つのカテゴリに分かれ占有C / C ++プログラムメモリ静态存储区动态存储区どちらのモードを以下に示します。

スタティック・メモリとダイナミックメモリに格納されたデータとの間の差である:の静的記憶領域编译-链接相プログラムは、変更されません実行している場合にのみ、プログラムが終了され、メモリは静的記憶領域回収システムとなり、同定されています。ダイナミックメモリは、プログラム動作時に動的に割り当てられています。

私たちは、他のメモリ割り当ての分類は、そのようなグローバルデータエリアなどの言葉定常領域など、すべてのこれらのセグメント、の分類がある見ることができる他の場所では、プロパティは、そのカテゴリのスタティックメモリです。

ここでは、メモリの分類上だけでおおよそのメモリの内容を表示することができます過去のノートについて、より詳細に、説明します。

[C言語]はメモリーノートノート

例:リターン・ポインタがスタックメモリへのポインタを返します

リターンを見ては、例のスタックへのメモリポインタのポイントを返します。

#include <stdio.h>

char *GetStr(void)
{
    char p[] = "Hello"; /* 保存在栈中 */
    return p;
}

int main(void) 
{
    char *str = NULL;
    str = GetStr();
    printf("%s\n", str);
    return 0;
}

プログラムがコンパイルされ、以下のように、操作の結果は以下のとおりです。

あなたは、コンパイラの警告を見ることができます:

警告:この関数は、ローカル変数のアドレスを返します。

当社の営業成績は、出力文字列を期待されていませんHello

であるGetStr関数は、変数pがローカル変数であるスタックメモリへのポインタポイントを返し、ローカル変数がスタックに割り当てられています。すなわちされHello、この時点でのpの内容が不明であるため、結果は何も出力されないので、スタックメモリは自動的に、関数呼び出しの終了時に破棄され、スタックメモリに格納されています。

ましょうGetStr、次のように機能が改正:

char *GetStr(void)
{
    char *p = "Hello";  /* p在栈上,Hello在静态区(常量区) */
    return p;
}

結果は、それが何であるのこの時刻に実行するようにコンパイル?結果は以下のとおりです。

あなたは、通常の出力を見ることができます。なぜそれがここにあると出力することができるが、通常の?Pここで、スタック上に割り当てられたが、この時間はもののためHelloスタティックメモリに記憶されている文字列定数、です。呼び出しではGetStr、関数の最後にそれが破壊されることはありません。

また、一部の人々が疑問を持っているがあるかもしれませんHello静的領域に、なぜスタックで、。

char *p = "Hello";

ポインタ変数pを定義するここでまず、コンパイラはスタックポインタ変数のためのスペースを開きます。そして、この時間と格納するスペースなしでHello、それがHello唯一の静的領域に格納することができます。

char p[] = "Hello";

配列サイズが指定されていないため、ここでPの最初に定義されたアレイは、アレイのサイズは、この時点では決定されません。そしてその後、Hello配列に格納され、コンパイラが配列Pの開口とストアに適切なスタックスペースを閉じるであろうHello

関連ノート:[ノート]列strをcharへのC言語のchar * strの[]の違い

他の代替

上記の例から、我々は、関数がスタックメモリへのポインタへのポインタを返した場合、得られた結果は、我々が望んでいないものをあることを知っています。上記方法に加えて、ここでいくつかの解決策があります。

グローバル変数は静的メモリ領域に格納されているため、図1に示すように、pは、グローバル変数として定義され、プログラムは解放を終了します。ただし、この機能はリエントラントではありませんが発生します。再入国し、再入国の機能は、期間にメモを見ることができません。

図2は、GetStr関数を使用するmalloc動的メモリを適用するために、私たちが使用使用することを覚えておく必要がありますfree解放されるように、それ以外の場合は、メモリリークにつながります。次のようにサンプル・コードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *GetStr(void)
{
    char *p = (char*)malloc(64*sizeof(char));
    strcpy(p, "Hello");
    return p;
}

int main(void) 
{
    char *str = NULL;
    str = GetStr();
    printf("%s\n", str);
    free(str);  /* 释放str指向的堆内存 */
    return 0;
}

3、p個の変数は、静的な静的変数として宣言することができます。しかし、それはまた、関数がリエントラントではありませんが発生します。次のようにサンプル・コードは次のとおりです。

char *GetStr(void)
{
    static char p[] = "Hello";
    return p;
}

これらは、間違っている場合は、指摘して下さい共有するには、このノートの内容です!


私の個人的なブログ:https://zhengnianli.github.io/
私のマイクロチャネル公共数:組み込みごった煮

おすすめ

転載: www.cnblogs.com/zhengnian/p/11491110.html