9

ブロックスコープでのstaticキーワードとmallocを使用する場合の利点は何ですか?

例えば:

機能A:

f() {
    static int x = 7;
}

機能B:

f() {
    int *x = malloc(sizeof(int));
    if (x != NULL)
        *x = 7;
}

これを正しく理解していれば、両方のプログラムが整数7を作成し、ヒープに格納されます。Aでは、変数は、mainメソッドが実行される前に、永続ストレージの最初に作成されます。Bでは、関数が呼び出されたらその場でメモリを割り当て、そのポインタが指す7を格納します。どのような状況で、ある方法を他の方法よりも使用する可能性がありますか?関数Aでxを解放できないことは知っているので、一般的にBの方が好ましいのではないでしょうか。

4

7 に答える 7

7

どちらのプログラムもinteger 7、ヒープに格納されるを作成します

いいえ、ありません。
staticプログラムの存続期間を通じて存続する静的ストレージ期間を持つオブジェクトを作成します。動的に割り当てられたオブジェクト(によって作成されたmalloc)は、によって明示的に削除されるまでメモリに残りfreeます。どちらも異なる機能を提供します。static動的に割り当てられたオブジェクトは維持しませんが、関数呼び出し内でオブジェクトの状態を維持します。

どのような状況で、ある方法を他の方法よりも使用する可能性がありますか?

staticプログラムの存続期間を通じてオブジェクトを存続させ、関数呼び出し内でその状態を維持する場合に使用します。マルチスレッド環境で作業している場合、同じstaticオブジェクトがすべてのスレッドで共有されるため、同期が必要になります。

オブジェクトの存続期間を明示的に制御する場合に使用mallocします。例:関数の呼び出し後に関数の呼び出し元がオブジェクトにアクセスするまで、オブジェクトが十分に長く存続することを確認します。(関数スコープが指定されると、自動/ローカルオブジェクトの割り当てが解除されます。{ }終了)。呼び出し元が明示的に呼び出さない限り、free割り当てられたメモリは、OSがプログラムの終了時に再利用するまでリークされます。

于 2013-03-06T04:06:30.113 に答える
0

関数Aでは、x静的ストレージ期間を割り当てています。これは、通常、ヒープ上(ほとんどの人が認識しているもの)ではないことを意味します。むしろ、プログラムの実行中ずっと存在することが保証されているのは単なるメモリです。

関数Bでは、関数に入るたびにストレージを割り当て、(free表示していない場合を除いて)そのメモリをリークします。

これらの2つの選択肢だけを考えると、機能Aが明らかに望ましいです。これには欠点がありますが(特にマルチスレッドに直面した場合)、少なくともそれが正しい状況がいくつかあります。関数B(現状)はまったく間違っています。

于 2013-03-06T04:07:16.280 に答える
0

スタックとヒープを忘れてください。それはここで起こっている最も重要なことではありません。

スコープstaticを変更することもあれば、ライフタイムを変更することもあります。典型的な例:

void int foo() {
     static int count = 0;
     return count++;
}

おそらくいくつかの異なる関数やファイルからでも、これを繰り返し呼び出してみてください。この場合、変数の存続期間はプログラムの実行全体と同じであるcountため、増加し続けることがわかります。static

于 2013-03-06T04:07:57.400 に答える
0

これを正しく理解していれば、両方のプログラムが整数7を作成し、ヒープに格納されます。

いいえ、静的変数はデータまたはBSSセグメントで作成され、プログラムの存続期間を通じて存続します。を使用して割り当てる場合malloc()、メモリはヒープに割り当てられ、呼び出しを使用して明示的に解放する必要がありfree()ます。

どのような状況で、ある方法を他の方法よりも使用する可能性がありますか?

同じ関数を複数回呼び出すために同じ変数にアクセスする場合は、最初のメソッドを使用します。つまり、この例では、xは1回だけ初期化され、メソッドを2回呼び出すと、同じx変数が使用されます。

関数を複数回呼び出すために変数を共有したくない場合は、2番目の方法を使用できます。これにより、この関数が2回目に呼び出され、xがmalloc再度呼び出されます。毎回xを解放する必要があります。

f()種類ごとに2回呼び出すと違いがわかりますf()

...
f();
f();
...

f(){
    static int x = 7;
    printf("x is : %d", x++);
}

f(){
   int *x = malloc(sizeof(int));
   if (x != NULL)
      *x = 7; 
   printf("x is : %d", (*x)++);
   free(x);   //never forget this,
}

結果は異なります

于 2013-03-06T04:08:34.450 に答える
0

http://www.teigfam.net/oyvind/pub/notes/09_ANSI_C_static_vs_malloc.htmlを読む

静的変数はmain()の前に作成され、プログラムの実行後にメモリを割り当てる必要はありません。

于 2013-03-06T04:12:23.293 に答える
0

まず最初に、static はストレージ クラスであり、malloc() は API であり、brk() システム コールをトリガーしてヒープにメモリを割り当てます。

これを正しく理解している場合、両方のプログラムがヒープに格納される整数 7 を作成しますか?

いいえ。静的変数は、プログラムに割り当てられたメモリのデータ セクションに格納されます。静的変数のスコープが終了しても、そのスコープ外でアクセスできますが、これは、データ セグメントの内容がスコープとは無関係に有効期間を持つことを示している可能性があります。

どのような状況で、ある方法を他の方法よりも使用する可能性がありますか?

特定のスコープ内でより多くの制御が必要な場合は、メモリの使用を制御しますmalloc()/free()。それ以外の場合は、静的を使用するのがより簡単な (そしてよりクリーンな) 方法です。

パフォーマンスの点では、変数 static を宣言する方が、ヒープに割り当てるよりもはるかに高速です。ヒープ管理のアルゴリズムは複雑であり、ヒープ リクエストの処理に必要な時間はアルゴリズムの種類によって異なるためです。

静的を提案するもう1つの理由は、静的変数はデフォルトでゼロに初期化されるため、心配する必要がもう1つ少なくなることです。

于 2013-03-06T04:19:15.333 に答える
0

以下の例を検討して、静的な仕組みを理解してください。通常、静的キーワードを使用して、変数または関数のスコープを定義します。たとえば、静的として定義された変数は、関数内で制限され、その値をリテールします。

ただし、以下のサンプル プログラムに示すように、静的変数の参照を他の関数に渡すと、他の関数から同じ変数を更新できます。

しかし、正確には、プログラムが終了すると static 変数が消滅します。つまり、メモリが解放されます。

#include <stdio.h>

void f2(int *j)
{
    (*j)++;
    printf("%d\n", *j);
}

void f1()
{   
    static int i = 10;
    printf("%d\n", i);
    f2(&i);
    printf("%d\n", i);  
}

int main()
{
    f1();       
    return 0;   
}

ただし、malloc() の場合、プログラマがプログラムの終了前に free() を使用してメモリを解放しない限り、メモリはプログラムの終了時に解放されません。

このようにして、malloc() を使用すると変数の寿命を制御できるようになりますが、注意してください...動的メモリ割り当てを選択するときは、メモリの割り当てと解放を非常に正確に行う必要があります。メモリを解放するのを忘れてプログラムが終了した場合、ヒープのその部分を使用して他のプロセスがメモリを割り当てることはできません。これにより、おそらく現実世界でメモリが不足し、計算が遅くなります。このような状況から抜け出すには、システムを手動で再起動する必要があります。

于 2013-03-06T06:07:01.950 に答える