8

アレイ関連の質問がいくつかあります。私は、配列サイズが宣言で一定でなければならない/コンパイラがその値を知らなければならないことを研究しました。newしかし、GNU GCC コンパイラ (C++11 標準フィルター) を使用すると、配列を動的に宣言するときに (を使用して) 、配列サイズとして変数を使用してプログラムを完全にコンパイルおよび実行できます。

int num;
cout << "How big an array? ";
cin >> num;
int *arr = new int [num];

質問 1) これは標準と見なされますか? 私の教授は矛盾しています。

質問2)標準である場合、その場合、作成後に配列(または任意の配列)のサイズを拡張することは可能ですか?

Ques3) 繰り返しますが、この式が標準である場合、関数内で使用することは可能ですか? 関数を使用してそのような配列を作成しますか? (もしそうなら、どのように?)

(PS: こんにちは、私はここに来たばかりで、C++ の初心者でもあります)

4

5 に答える 5

7

質問 1) これは標準と見なされますか? 私の教授は矛盾しています。

はい、これは完全に有効です。arroperator を使用してポイントされたメモリを明示的に削除する必要があることに注意してくださいdelete[]std::vector<int>メモリ管理を実行するを使用する方がはるかに優れています。

では許可されていない可変長配列 (VLA) と間違えている可能性がありますC++

// same num as the one in your example
int arr[num]; // ERROR

これは有効ですがC、無効ですC++(C++14 には VLA が含まれますが、VLA とはいくつかの違いがありCます)。

質問2) 標準である場合、その場合、作成後に配列(または任意の配列)のサイズを拡張することは可能ですか?

いいえ、延長できません。より大きな配列を割り当て、要素をコピーして、前の要素を削除できます。繰り返しますが、これは を使用している場合は自動的に行われますstd::vector<int>

Ques3) 繰り返しますが、この式が標準である場合、関数内で使用することは可能ですか? 関数を使用してそのような配列を作成しますか? (もしそうなら、どのように?)

はい、もちろん:

int *allocate(size_t size) {
    return new int[size];
}

しかし、再び使用std::vectorします:

int num;
cout << "How big an array? ";
cin >> num;
std::vector<int> arr(num); // num elements, all of them initialized to 0
// insert 42 at the end. reallocations(if any) are done automatically
arr.push_back(42); 
于 2013-06-13T01:51:11.690 に答える
0

Q1:これは標準と見なされますか?

int n = 42 という定義が与えられた場合、new float[n][5] は整形式ですが (n は noptr-new-declarator の式であるため)、new float[5][n] は整形式ではありません ( n は定数式ではありません)。-- 5.3.4.6、N3242

割り当てられた型が配列型の場合、割り当て関数の名前は operator new[] であり、解放関数の名前は operator delete[] です。
-- 5.3.4.8、N3242

new T[5]operator new[](sizeof(T)*5+x) ここで、x と y は、配列割り当てのオーバーヘッドを表す非負の未指定の値です。
-- 5.3.4.12、N3242

Q2:標準であれば、作成後に配列(または任意の配列)のサイズを拡張することは可能ですか?

部分的にいいえ、または推奨されません。
割り当て関数が null 以外の値を返す場合、それは、オブジェクト用のスペースが予約されているストレージのブロックへのポインターでなければなりません。ほとんどの割り当てはヒープで発生し、配列にとって重要な連続したメモリが残っていない可能性があります。
これを行う必要があり、メモリ ポーリングが必要な場合は、placement new 演算子を使用してこれを部分的に行うことができますが、今行うことはアロケータの設計者が行うことであり、内部メモリ ストレージを台無しにするリスクがあります。

Q3: 関数を使用してそのような配列を作成しますか? (もしそうなら、どのように?)

new-expression によって作成されたエンティティには、動的ストレージ期間 (3.7.4) があります。[注: そのようなエンティティの有効期間は、必ずしもそれが作成されたスコープに制限されるわけではありません。— 末尾の注記 ] -- 5.3.4.1,N3242

残りは、テンプレートを使用して、必要に応じてそのような機能を設計する方法です。

 1 template<typename T>T* foo(std::size_t size){
 2         return new T[size] ;
 3 }
于 2013-06-13T10:07:23.870 に答える