1. 程式人生 > >動態分配、刪除二維陣列

動態分配、刪除二維陣列

下面三種定義形式怎麼理解?怎麼動態分配空間?
        (1)、int **Ptr;
        (2)、int *Ptr[ 5 ]; 我更喜歡寫成 int* Prt[5];
        (3)、int ( *Ptr )[ 5 ];

以上三例都是整數的二維陣列,都可以用形如 Ptr[ 1 ][ 1 ] 的方式訪問其內容;但它們的差別卻是很大的。

下面我從四個方面對它們

 一、內容:
        它們本身都是指標,它們的最終內容都是整數。注意我這裡說的是最終內容,而不是中間內容,比如你寫 Ptr[ 0 ],對於三者來說,其內容都是一個整數指標,即 int *;Ptr[ 1 ][ 1 ] 這樣的形式才是其最終內容。

二、意義:
        (1)、int **Ptr 表示指向"一群"指向整數的指標的指標。
        (2)、int *Ptr[ 5 ] 表示指向 5 個指向整數的指標的指標,或者說Ptr有5個指向"一群"整數的指標,Ptr是這5個指標構成的陣列的地址
        (3)、int ( *Ptr )[ 5 ] 表示指向"一群"指向 5 個整數陣列的指標的指標。

三、所佔空間:
        (1)、int **Ptr 和 (3)、int ( *Ptr )[ 5 ] 一樣,在32位平臺裡,都是4位元組,即一個指標。
        但 (2)、int *Ptr[ 5 ] 不同,它是 5 個指標,它佔5 * 4 = 20 個位元組的記憶體空間。
四、用法:
        (1)、int **Ptr

        因為是指標的指標,需要兩次記憶體分配才能使用其最終內容。首先,Ptr = ( int ** )new int *[ 5 ];這樣分配好了以後,它和(2)的意義相同了;然後要分別對 5 個指標進行記憶體分配,例如:Ptr[ 0 ] = new int[ 20 ];它表示為第 0 個指標分配 20 個整數,分配好以後, Ptr[ 0 ] 為指向 20 個整數的陣列。這時可以使用下標用法 Ptr[ 0 ][ 0 ] 到Ptr[ 0 ][ 19 ] 了。

        如果沒有第一次記憶體分配,該 Ptr 是個"野"指標,是不能使用的,如果沒有第二次記憶體分配,則 Ptr[ 0 ] 等也是個"野"指標,也是不能用的。

#include "stdafx.h"
#include <stdio.h> 
#include <iostream>
using namespace std;

int main(int argc, char* argv[]) 
{ 
  int x = 3, y = 4;
  int i=0;
  int **p = new int*[x];//建立一個動態int* 型陣列
  for( i = 0; i < x; ++i)   
      p[i] = new int[y]; //再建立一個動態int 型陣列  

  //測試
  int m,n;
  for( m=0; m<x ; ++m)
   for( n=0; n<y; ++n)
    p[m][n] = m*10+n;
  for( m=0; m<x ; ++m)
   for( n=0; n<y; ++n)
    cout<<p[m][n]<<endl;

  for ( i = 0; i < x; ++i)   
  {   
     delete[] p[i];   
     //由裡至外,進行釋放記憶體。   
     p[i] = NULL;
     //不要忘記,釋放空間後p[i]不會自動指向NULL值,還將守在原處,只是釋放記憶體而已,僅此而已。   
  }   
  delete []p;   
  p = NULL;  

  return 0; 
}

       (2)、int *Ptr[ 5 ]
       這樣定義的話,編譯器已經為它分配了 5 個指標的空間,這相當於(1)中的第一次記憶體分配。根據對(1)的討論可知,顯然要對其進行一次記憶體分配的。否則就是"野"指標。
       (3)、int ( *Ptr )[ 5 ]
       它的意義是"一群"指標,每個指標都是指向一個 5 個整數的陣列。如果想分配 k 個指標,這樣寫: Ptr = ( int ( * )[ 5 ] ) new int[ 5 * k ]。
這是一次性的記憶體分配。分配好以後,Ptr 指向一片連續的地址空間,其中 Ptr[ 0 ] 指向第 0 個 5 個整數陣列的首地址,Ptr[ 1 ] 指向第1 個 5 個整數陣列的首地址。
    

綜上所述,我覺得可以這樣理解它們:
    int ** Ptr &lt;==> int Ptr[ x ][ y ];
    int *Ptr[ 5 ] <==> int Ptr[ 5 ][ x ];
    int ( *Ptr )[ 5 ] <==> int Ptr[ x ][ 5 ];