2017-03-27 48 views
0

ARRは、以下のように関数を転置し、[0]、それは元の$ 00 ... 001を与えることなくされるの内容を検査するために渡されます。住所はarrとなっています。どうしてそれが間違っていますか?私は[0]が配列の1のアドレスであり、[0] [1]が配列の最初の要素であると考えます。説明してください。C++ 2次元配列とポインタ参照

問題:例外をスロー

int arr[][4] = { { 1, 2, 3, 4},{ 5, 6,7,8 },{ 9,10,11,12 } }; 
    transpose((int **)arr, 3, 4); 
    int** transpose(int** a, int m, int n) 
    { 
     int** output = new int*[n]; 
     for (int i = 0;i < m;i++) 
     { 
      output[i] = new int[n]; 
     } 
     for (int i = 0;i < m;i++) 
     { 
      for (int j = 0;j < n;j++) 
      { 
       //*((output[j]) + i) = *(a[i] + j); 
       //*((output[j]) + i) = a[i][j]; 
       output[j][i] = a[i][j]; 
      } 
     } 
     return output; 
    } 

が正常に動作します:すべての

int** output=transpose((int *)arr, 3, 4); 
    print(output,3,4); 
    int**transpose(int * a, int m, int n) 
    { 
     int** t = new int*[n]; 
     for (int i = 0;i < n;i++) 
     { 
      t[i] = new int[m]; 
     } 
     for (int i = 0;i < m;i++) 
     { 
      for (int j = 0;j < n;j++) 
      { 
       t[j][i] = *((a + i*n) + j); 
      } 
     } 
     return t; 
    } 

    void Matrix::print(int ** a, int m, int n) 
    { 
     for (int i = 0;i < m;i++) 
     { 
      for (int j = 0;j < n;j++) 
      { 
       std::cout << a[i][j] << ","; 
      } 
      std::cout << "\n"; 
     } 
    } 
+0

「投げ出し例外」が何を意味するのか分かりません。 –

+0

最初のメソッドで[i] [j]にアクセス中にアクセス違反例外がスローされています。それはメモリを読み取ることができないことを伝えています。 – Curious

+1

'(int **)arr'は間違いです。あなたは配列とポインタの違いを理解していないようです。転置関数は2次元配列では使用できません。 –

答えて

1

コードを2次元配列で使用するには、コードを次のように変更する必要があります。

int arr[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; 
transpose(&arr, 3, 4); 

int** transpose(int(*a)[3][4], int m, int n) 
{ 
    int** output = new int*[n]; 
    for (int i = 0; i < m; i++) 
    { 
     output[i] = new int[n]; 
    } 
    for (int i = 0; i < m; i++) 
    { 
     for (int j = 0; j < n; j++) 
     { 
      //*((output[j]) + i) = *(a[i] + j); 
      //*((output[j]) + i) = a[i][j]; 
      if (i < n && j < m) 
      { 
       output[j][i] = (*a)[i][j]; 
      } 
     } 
    } 
    return output; 

パラメータ宣言int(*a)[3][4]を見てください。変数aは、サイズ[2] [4]の2次元配列へのポインタです。追加のチェックif (i < n && j < m)は、アレイへのアクセスが境界外にならないようにします。

これは例外なく動作します。

0

まずあなたの例では、Mが3でNトランスポーズ機能であなたが出力を作成しているので、4であるN(4)あなたは0からm(3)のforループを持っているので、この時点で出力は既に初期化されていない要素(出力[3])を持っています。クラッシュする理由は、次のループでその初期化されていない要素を使用することです。

+0

最初のメソッドで[i] [j]にアクセス中にアクセス違反例外がスローされています。それはメモリを読み取ることができないことを伝えています。 – Curious