【原】動態申請二維數組並釋放的三種方法


在C++中實現變長數組 

一般來說,有三種方法來申請多維數組:C的malloc/Free    C++的new/delete    STL容器Vector


1.變長一維數組 

這里說的變長數組是指在編譯時不能確定數組長度,程序在運行時需要動態分配內存空間的數組。實現變長數組最簡單的是變長一維數組,你可以這樣做: 

//文件名:   array01.cpp 
#include <iostream> 
using   namespace   std; 

int   main() 

  int   len; 
  cin> > len; 
  //用指針p指向new動態分配的長度為len*sizeof(int)的內存空間 
  int   *p=new   int[len]; 
  ........... 
  delete[]   p; 
  return   0; 


注意int   *p=new   int[len];這一句,你不能這樣做: 
int   p[len]; 
C++編譯器會報錯說len的大小不能確定,因為用這種形式聲明數組,數組的大小需要在編譯時確定。而且這樣也不行: 
int   p[]=new   int[len]; 
編譯器會說不能把int*型轉化為int[]型,因為用new開辟了一段內存空間后會返回這段內存的首地址,所以要把這個地址賦給一個指針,所以要用int   *p=new   int[len]; 

array01.cpp實現了一個變長的一維數組,但是要養成一個好習慣,就是注意要注銷指針p,使程序釋放用new開辟的內存空間。 
當然使用C++標准模版庫(STL)中的vector(向量)也可以實現變長數組: 

//文件名:   array02.cpp 
#include <iostream> 
#include <vector> 
using   namespace   std; 

int   main() 

  int   len; 
  cin> > len; 
  vector <int>   array(len);//聲明變長數組 

  for(int   i=0;i <len;i++) 
  { 
    array[i]=i; 
    cout < <array[i] < < "\t "; 
  } 
  return   0; 


這里的變長數組讓我聯想到了java的java.util包中的vector和C#中的ArrayList,它們也可以在各自的語言中實現變長數組。不過C++中的vector不能像C#一樣有托管的垃圾回收機制回收被占用的內存空間,但是你可以在使用完vector后調用~vector()析構函數釋放內存。 

2.變長n維數組 
變長的n維數組實現起來有些麻煩,但是在工程與軟件設計應用中常使用的是二維數組,所以在這里着重介紹變長的二維數組,變長的n維數組可以按照類似的方法實現。首先看一個經典的用C實現變長二維數組的例子: 

//文件名:   array03.c 
#include     <stdio.h>     
#include     <malloc.h>     
  
void     main()     
                          
{     
                      int     x,y,i,j;     
                      float     **a,*b;     
                                              printf( "請輸入你所求解的線性方程組的行數x:x= ");     
                      scanf( "%d ",&x);     
                                              printf( "請輸入你所求解的線性方程組的列數y:y= ");     
                      scanf( "%d ",&y);     
  
              a=(float     **)malloc(sizeof(float     *)     *x);     
              b=(float     *)malloc(sizeof(float)     *x);     
                      for(i=0;i <x;i++)     
                      {     
                                              *(a+i)=(float     *)malloc(sizeof(float)     *y);     
                      }     
  
/*讀入數據*/     
  
                      printf( "請按行的順序依次輸入系數的值(共%d項): ",x*y);     
                      for(i=0;i <=x-1;i++)     
                                              for(j=0;j <=y-1;j++)     
                                                                      scanf( "%f ",&a[i][j]);     
                      printf( "請按列的順序依次輸入常數的值(共%d項): ",x);     
                      for(j=0;j <=x-1;j++)     
                                                                      scanf( "%f ",&b[j]);     
  
                      printf( "您輸入方程組的增廣矩陣為:\n ");     
                      for(i=0;i <=x-1;i++)     
                      {     
                                              for(j=0;j <=y-1;j++)     
                                                                      printf( "%.5f         ",a[i][j]);     
                                              printf( "%.5f         ",b[i]);     
                                              printf( "\n ");     
                      }     
                      free(b);     
                      for(i=0;i <x;i++)     
                                              free     (*(a+i));     
  


那么用C++怎樣實現呢?在C++中可以通過new和delete運算符動態開辟和釋放空間,其中new與C中malloc函數的功能相似,delete與C中free函數的功能相似。用C++實現變長二維數組時可以采用兩種方法:雙指針方法和使用STL中vector(向量)的方法。 

首先介紹一下雙指針方法,在這里雙指針就是指像指針的指針,比如你可以這樣聲明一個數組: 
int   **p   =   new   int*[num1]; 
而對每一個*p(一共num1個*p)申請一組內存空間: 
for(int   i=0;   i <num1;   ++i) 
  p[i]   =   new   int[num2]; 
其中,num1是行數,num2是數組的列數。測試的源程序如下: 

//文件名:   array04.cpp 
#include   <iostream> 
#include   <iomanip> 
using   namespace   std; 

int   main() 

  int   num1,//行數 
          num2;//列數 

  cout < < "Please   enter   the   number   for   row   and   column:   " < <endl; 
  cin   > >   num1   > >   num2; 

  //為二維數組開辟空間 
  int   **p   =   new   int*[num1]; 
  for(int   i=0;   i <num1;   ++i) 
    p[i]   =   new   int[num2]; 

  for(int   j=0;j <num1;j++) 
  { 
    for(int   k=0;k <num2;k++) 
    { 
      p[j][k]=(j+1)*(k+1); 
      cout < <setw(6) < <p[j][k] < < ': ' < <setw(8) < <&p[j][k]; 
    } 
    cout < <endl; 
  } 

  //釋放二維數組占用的空間 
  for(int   m=0;m <num1;m++) 
    delete[]   p[m]; 
  delete[]   p; 

  return   0; 


以下是運行結果: 

Please   enter   the   number   for   row   and   column: 
4   5 
          1:004915F0           2:004915F4           3:004915F8           4:004915FC           5:00491600 
          2:00491180           4:00491184           6:00491188           8:0049118C         10:00491190 
          3:00491140           6:00491144           9:00491148         12:0049114C         15:00491150
          4:00491100           8:00491104         12:00491108         16:0049110C         20:00491110 
Press   any   key   to   continue 

程序清單array04.cpp可以顯示分配的內存空間單元的地址,大家可以看到,由於數組空間是動態分配的,數組行之間的地址空間是不連續的,因為不同行的數組元素的地址空間是用不同的new來分配的。而每一行之中列之間的地址空間是連續的。 

那么用vector(向量)怎樣實現二維數組呢?以下給出源程序: 

//文件名:   array05.cpp 
#include   <iostream> 
#include   <vector> 
#include   <iomanip> 
using   namespace   std; 
int   main() 

  int   i, 
          j, 
          m,   //行數 
          n;   //列數 

  cout   < <   "input   value   for   m,n: "; 
  cin> > m> > n; 
  
  //注意下面這一行:vector <int后兩個 "> "之間要有空格!否則會被認為是重載 "> > "。 
  vector <vector <int>   >   vecInt(m,   vector <int> (n));     
  for   (i   =   0;   i   <   m;   i++) 
    for   (j   =   0;   j   <   n;   j++) 
      vecInt[i][j]   =   i*j;   
      
  for   (i   =   0;   i   <   m;   i++) 
  { 
    for   (j   =   0;   j   <   n;   j++) 
      cout < <setw(5) < <vecInt[i][j] < < ": " < <setw(9) < <&vecInt[i][j]; 
    cout < <endl; 
  } 

  return   0; 


以下是運行結果: 

input   value   for   m,n:3   4 
        0:   00491180         0:   00491184         0:   00491188         0:   0049118C 
        0:   00491140         1:   00491144         2:   00491148         3:   0049114C 
        0:   00491100         2:   00491104         4:   00491108         6:   0049110C 
Press   any   key   to   continue 

大家可以看到,這里vector中元素的內存的地址分配也有同雙指針實現的二維數組有同樣的特點。不過用vector的方法比使用雙指針簡單地多,分配內存空間時會更安全,數組初始化代碼也更簡單,所以本人建議使用STL中的vector來實現變長多維數組。以下是一個變長三維數組:) 

//文件名:   array06.cpp 
#include   <iostream> 
#include   <vector> 
#include   <iomanip> 
using   namespace   std; 
int   main() 

  int   i, 
    j, 
    k, 
    m,   //一維坐標 
    n,   //二維坐標 
    l;   //三維坐標 
    

  cout   < <   "input   value   for   m,n,l: "; 
  cin> > m> > n> > l; 
  vector <vector <vector <int>   >   >   vecInt(m,   vector <vector <int>   > (n,   vector <int> (l)));     
  for   (i   =   0;   i   <   m;   i++) 
    for   (j   =   0;   j   <   n;   j++) 
      for(k   =   0;   k   <   l;   k++) 
        vecInt[i][j][k]   =   i+j+k;   
      
  for   (i   =   0;   i   <   m;   i++) 
  { 
    for   (j   =   0;   j   <   n;   j++) 
    { 
      for(k   =   0;   k <l;   k++) 
        cout < <setw(5) < <vecInt[i][j][k] < < ": " < <setw(9) < <&vecInt[i][j][k]; 
      cout < <endl; 
    } 
    cout < <endl; 
  } 

  return   0; 


運行結果: 
input   value   for   m,n,l:2   3   4 
        0:   00492FE0         1:   00492FE4         2:   00492FE8         3:   00492FEC 
        1:   00492FA0         2:   00492FA4         3:   00492FA8         4:   00492FAC 
        2:   00492F60         3:   00492F64         4:   00492F68         5:   00492F6C 

        1:   00492EC0         2:   00492EC4         3:   00492EC8         4:   00492ECC 
        2:   00492E80         3:   00492E84         4:   00492E88         5:   00492E8C 
        3:   00492E40         4:   00492E44         5:   00492E48         6:   00492E4C 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM