2016-08-16 6 views
1

は、私が受験のための勉強とテスト受験中に、彼らはへのポインタのポインタオブジェクトを使用して、動的に作成する必要性を置くptr-to-ptr配列の使用?このような何かを使用すると説明がある何

int capacity; 
int** number; 
this->number = new int*[this->capacity]; 

?:しますそれからの配列。 2つのクラスがあります。 ウォレット & ウォレットキーパー

private: 
    Wallet** wallets; 
    int capacity; 
    int size; 
    /*other stuff below this*/ 

そしてコンストラクタで:彼らはWalletKeeperのヘッダ・ファイルでこれをやったソリューションで

Wallet * wallets = new Wallet[capacity]; 

WalletKeeper::WalletKeeper(int capacity) 
{ 
    this->capacity = capacity; 
    this->size = 0; 
    this->wallets = new Wallet*[this->capacity]; 
    this->initiate(); 
} 

私はこのような基本的な動的配列を理解しますこれは、このウォレットの配列が作成されたメモリ内の場所を指すポインタを作成することを意味します。そのため、それらのメモリスロットの内容を変更することができます。 しかし、なぜあなたはポインタの配列へのポインタを作るでしょうか?使用は何ですか?私はこれを読んでいるので

財布は、自分自身の配列を持っていない、私はそうでない場合は、それを理解しただろう:The correct way to initialize a dynamic pointer to a multidimensional array?

教授はさらに騒ぎまで休暇にしています。

+0

なぜあなたは今までに他の配列を含むことができ、配列の配列を作るのでしょうか?たとえば、行列は配列の配列として表すことができます(各行の数値の配列、行列全体は単なる列の配列です)。 – ForceBru

+6

私は答えに取り組んでいますが、私がする前に、私はこのような教授がまだC++を教えていることを驚かせています。 'std :: vector 'または 'std :: vector >'オブジェクトを使用するように教えておかなければなりませんでした。どちらも、このエラーを起こしやすく、実用的なアプリケーションコードです。 – Xirema

+1

Wallet *の配列です。これは "自然な"現代的なC++ではなく、コンテナクラスを使って行う必要があり、可能な場合は一般的にメモリの未使用割り当ては避けるべきです。 – crashmstr

答えて

1

基本的な考え方は、「配列の配列」を作成できるということです。これは、サブアレイのサイズを異ならせることができるという点で、マトリックスよりも狭い利点を持っていますが、すべてのオブジェクトのメモリがアレイ全体ではもはや連続していないという欠点があります。そのコードでは、w_ptr_ptr[0]w_ptr_ptr[1]より異なるサイズのアレイを有すること

Wallet ** w_ptr_ptr = new Wallet*[capacity]; 
for(int i = 0; i < capacity; i++) { 
    w_ptr_ptr[i] = new Wallet[i+1]; 
} 

for(int i = 0; i < capacity; i++) { 
    for(int j = 0; j < i+1; j++) { 
     w_ptr_ptr[i][j] = Wallet(/*...*/); 
    } 
} 

注。

私のコメントにも触れたように、あなたの教授はこのように教えるべきではありません。このコードは、手動メモリのクリーンアップを必要とし、チェックの自動境界を行うにはどんな能力を持っていないので、あなたが使用する必要がありますコードは次のとおりです。

std::vector<std::vector<Wallet>> wallets; 

for(int i = 0; i < capacity; i++) { 
    wallets.emplace_back(i+1); //Will automatically create a i+1-sized array. 
} 

for(int i = 0; i < wallets.size(); i++) { //Note I'm able to query the size here! 
    for(int j = 0; j < wallets[i].size(); j++) { //Again I can query the size! 
     wallets[i][j] = Wallet(/*...*/); 
    } 
} 
+0

もっと多くのコードを見ることなく、 'Wallet'の配列や' Wallet * 'の配列だけであるとは想定できません。私にとっては、「Wallet *」を保持する「WalletKeeper」を予定している方が理にかなっています。 – crashmstr

+0

@crashmstrまあ、ポインタ配列(Wallet *)を指し示すptr2ptr(Wallet **)しか存在せず、どこにも指していない場合があります。だから私は混乱している、彼らはそれぞれ配列を指している場合、私はそれを理解していただろう。 –

+0

その後、コードは後のステップとしてポインタに 'new Wallet'を割り当てるか割り当てます。これを行う "理由"は、あなたが 'Wallet'オブジェクトを前に配置しないためです。あなたは安全にするために配列を 'nullptr'に初期化する必要があります(また、スロットが占有されているかどうかを確認できます)。 – crashmstr

3

ポインタの配列には多くの用途があります。

  1. 並べ替え。配列内のオブジェクトの順序を変更したいとします。ポインタを扱うことは、オブジェクト全体を移動するよりもはるかに高速です。
  2. 動的割り当て。各オブジェクトを個別に削除または割り当てることができます。
  3. 再割り当てとパフォーマンス。配列のサイズを大きくしたいとします。実際のオブジェクトを再割り当てすると、さまざまな種類の問題(無効化)が発生する可能性があります。しかし、ポインタの配列を再配置することは多かれ少なかれ問題がなく、またはるかに高速です。
+0

これに加えて、ポインタ配列には配列内のいくつかの要素が同一である必要がある場合は、ポインタを再利用することで多くのメモリを節約できます。 –

0

ポインタ・オブジェクトへのポインタが行列実装に共通に使用されます。

Wallet* wallets = new Wallet[capacity]; 

はNUM容量Walletオブジェクトへの配列の最初の場所を指して財布を作る:あなたがあなたの質問に提案してきたように実際のオブジェクトへのポインタなどは、動的配列を実装します。

[Wallet-obj] [Wallet-obj] [Wallet-obj] ... [Wallet-obj] 
    0   1    2   capacity - 1 

ようなポインタのポインタ:

Wallet** wallets = new Wallet*[capacity]; 

ウォレットポインタの配列を作成します。

[Wallet-pointer] [Wallet-pointer] [Wallet-pointer] ... [Wallet-pointer] 
     0    1     2    capacity-1 

各ポインタをベクトルに動的配列を指す必要があります。

I表現を "描く" しようとするでしょう:

[0][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj] 
[1][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj] 
... 
[capacity-1][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj] 

だからあなたのようなものを使用するオブジェクトにアクセスするために:1-STへのアクセスを意味

wallets[0][2]; 

をその行の3番目のオブジェクトへのオブジェクトアクセスの1 "行"を使用して、ポインタの配列内のポインタを返します。

イメージできるように、n個の容量の行のようなn個の容量の動的配列があるため、行列があります。

あなたはポインタの配列をインスタンス化注意

は、あなたはそれらのそれぞれを初期化する必要があります。 これは完全なコードです:

Wallet** wallets = new Wallet*[capacity]; 

// Now for each pointer you have to allocate a dynamic array of n-elements. 
for (size_t i = 0; i < capacity; ++i) { 
    wallets[i] = new Wallet[capacity]; 
} 

そして、同じことが割り当て解除段階のためである:

// First of all, deallocate each object in each dynamic array: 
for (size_t i = 0; i < capacity; ++i) { 
    delete[] wallets[i]; // wallets[i] is a dynamic array to deallocate 
} 

// Finally deallocate the dynamic array of poiter 
delete[] wallets; 
関連する問題