web-dev-qa-db-ja.com

C ++の静的配列と動的配列

C++の静的配列と動的配列の違いは何ですか?

クラスに割り当てを行う必要がありますが、静的配列を使用せず、動的配列のみを使用するように指示しています。私は本とオンラインで調べましたが、理解していないようです。

コンパイル時に静的に作成され、実行時に動的に作成されると考えましたが、これをメモリ割り当てと間違えている可能性があります。

C++の静的配列と動的配列の違いを説明できますか?

78
user69514

ローカルアレイはスタック上に作成され、自動保存期間があります。メモリを手動で管理する必要はありませんが、機能が終了すると破棄されます。それらは必然的に固定サイズを持ちます:

int foo[10];

operator new[]で作成された配列は、動的な保存期間を持ち、ヒープ(技術的には「フリーストア」)に保存されます。サイズは任意ですが、スタックフレームの一部ではないため、自分で割り当てて解放する必要があります。

int* foo = new int[10];
delete[] foo;
87
Michael Mrozek

staticはCおよびC++のキーワードであるため、変数または配列に適用される場合、静的は一般的な説明用語ではなく、非常に具体的な意味を持ちます。混乱を複雑にするために、別々のコンテキスト内で3つの異なる意味を持ちます。このため、静的配列は固定または動的のいずれかです。

説明させてください:

1つ目はC++固有です。

  • 静的クラスメンバは、コンストラクタでインスタンス化されないか、デストラクタで削除されない値です。これは、メンバーを他の方法で初期化し、維持する必要があることを意味します。静的メンバーは、nullに初期化されたポインターであり、コンストラクターが最初に呼び出されたときに割り当てられます。 (はい、それは静的および動的です)

2つはCから継承されます。

  • 関数内の静的変数とは、関数呼び出し間でメモリの場所が保持される変数です。一度だけ初期化され、関数呼び出し間でその値を保持するという点で静的です(静的関数を使用すると、関数は再入不可能になります。つまり、スレッドセーフではありません)

  • 関数の外部で宣言された静的変数は、同じモジュール(他の#includeを含むソースコードファイル)内からのみアクセスできるグローバル変数です。

あなたが尋ねることを意図した質問(私は思う)は、動的配列と固定配列またはコンパイル時配列の違いは何ですか。これは簡単な質問です。コンパイル時配列は事前に決定され(プログラムのコンパイル時)、関数スタックフレームの一部です。メイン関数が実行される前に割り当てられます。動的配列は、実行時に「new」キーワード(またはCのmallocファミリ)を使用して割り当てられ、そのサイズは事前にわかりません。プログラムが実行を停止するまで、動的割り当ては自動的にクリーンアップされません。

27
Joshua Clayton

クラスで使用されているセマンティクスは紛らわしいと思います。おそらく「静的」が意味するのは単に「一定のサイズ」であり、おそらく「動的」が意味するのは「可変サイズ」です。その場合、一定サイズの配列は次のようになります。

int x[10];

そして、「動的」なものは、基礎となるストレージを実行時に増減できるようにするあらゆる種類の構造です。ほとんどの場合、C++標準ライブラリのstd::vectorクラスで十分です。次のように使用します。

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.

std::vectorにはoperator[]が定義されているため、配列と同じセマンティクスで使用できます。

11
Ben Collins

用語の意味を明確に定義することが重要です。残念ながら、静的配列と動的配列の意味については複数の定義があるようです。

静的変数静的メモリ割り当て を使用して定義された変数です。これは、C/C++に依存しない一般的な概念です。 C/C++では、次のようにグローバル、ファイル、またはローカルスコープを持つ静的変数を作成できます。

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope

自動変数 は、通常 スタックベースのメモリ割り当て を使用して実装されます。次のように、C/C++で自動配列を作成できます。

foo() {
    int w[10]; //automatic array

これらの配列x, y, zおよびwの共通点は、それぞれのサイズが固定され、コンパイル時に定義されることです。

自動配列と静的配列の違いを理解することが重要である理由の1つは、通常、静的ストレージが dataセクション (または BSSセクション )で実装されていることですオブジェクトファイルとコンパイラは、絶対アドレスを使用して配列にアクセスできます。これはスタックベースのストレージでは不可能です。

通常、 動的配列 が意味するのは、サイズ変更が可能なものではなく、実行時に決定される固定サイズで 動的メモリ割り当て を使用して実装されるものです。 C++では、これは new演算子 を使用して行われます。

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     

ただし、allocaを使用して、実行時に定義された修正サイズで自動配列を作成できます。

foo() {
    int *s = (int*)alloca(n*sizeof(int))

真の動的配列の場合、C++のstd::vector(または Cの可変長配列 )のようなものを使用する必要があります。

OPの質問の課題の意味は何ですか?私が望んでいたのは、静的または自動の配列ではなく、new演算子を使用した動的なメモリ割り当て、またはたとえばstd::vector

8
Z boson

静的配列にはコンパイル時にメモリが割り当てられ、メモリはスタックに割り当てられます。一方、動的配列には実行時にメモリが割り当てられ、メモリはヒープから割り当てられます。

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.
8
Jagannath

この文脈では、サイズが固定されているという意味で静的であることを意味すると思います。 std :: vectorを使用します。 resize()関数があります。

3
Eddy Pronk

実行時にユーザーがサイズを設定する疑似動的配列を使用できますが、その後は固定されます。

int size;
cin >> size;
int dynamicArray[size];
1
Joshua Oliphant

はい、コンパイル時に静的配列が作成されますが、実行時に動的配列が作成されます。違いがメモリの場所に関する限り、静的はスタック上にあり、動的はヒープ上に作成されます。ヒープ上に配置されるすべてのものは、.netフレームワークの場合のようにガベージコレクターが存在するまでメモリ管理が必要です。そうでない場合は、メモリリークのリスクがあります。

0
Aadil Imran

静的配列:効率。動的な割り当てまたは割り当て解除は必要ありません。

Static修飾子を含む関数でC、C++で宣言された配列は静的です。例:static int foo [5];

0
Khuê Phạm