2016-11-11 16 views
1
vector< vector<int> > resizeVector(vector< vector<int> > m) 
{ 
    vector< vector<int> > newMatrix; 
    int i,j; 

    for (i = 0; i < m[i].size(); i++) 
    { 
     for(j = 0; j < m[j].size(); j++) 
     { 
      newMatrix[i][j] = m[i][j]; 
     } 
    } 
    return (newMatrix); 
} 

私は、たくさんの行列操作を行うプログラムを作成しています。このセクションはクラッシュしています。私はそれを次の行に絞りました:ベクトル割り当てのクラッシュ、わからない理由

newMatrix[i][j] = m[i][j]; 

ここではクラッシュしていますが、その理由はわかりません。

答えて

0

チェックが間違っています。代わりに、それはあなたが最初にそのサイズを設定せずに、あなたの新しいnewMatrixに代入している

for (i = 0; i < m.size(); i++)  // m.size() gives the number of rows 
{ 
    for(j = 0; j < m[i].size(); j++) // m[i].size() gives the number of columns in the row 
0

でなければなりません。デフォルトでは空になり、には、に割り当てようとすると未定義の動作になります。

新しいサイズを渡すことはないので、達成しようとしていることを正確に知ることは難しいです。だから私はそれを修正する方法についてもっと明確な助言をしていないのです。

1

@Sauravが投稿した内容に加えて、newMatrixは空ですので、newMatrix[i][j]に値を割り当てることはできません。ループのために、我々は(ベクトルはそれらのデフォルトコンストラクタに空になっている)、それの内部m.size()多くの空のベクトルを持っているnewMatrixを初期化する前に

vector< vector<int> > resizeVector(vector< vector<int> > m) 
{ 
    vector< vector<int> > newMatrix(m.size()); 
    int i,j; 

    for (i = 0; i < m.size(); i++) 
    { 
     newMatrix[i].resize(m[i].size()); 
     for(j = 0; j < m[i].size(); j++) 
     { 
      newMatrix[i][j] = m[i][j]; 
     } 
    } 
    return (newMatrix); 
} 

:あなたは、与えられたサイズのベクトルを初期化することによってこの問題を解決することができます。外側forループの各繰り返しの間に、resizeメンバ関数を使用して、newMatrix内の各ベクトルが正しいサイズを持つようにします。

vector< vector<int> > newMatrix(m); 
0

を使用すると、ベクトルのベクトルを割り当てたい場合、あなたはそれにあなたのインデックスの前に行列用のメモリを割り当てる必要があります:あなたは、ベクターのコピーをしたい場合は、単純に書くことができることを

注意。だから、

newMatrix.resize(size); 
for (int i = 0; i < size; ++i) { 
    newMatrix[i].resize(size); 
} 

それとも、事前にメモリを割り当てることなく、ベクターに値を追加する()ベクター法を.push_back使用できるようなものを使用する必要があります。

0

vectors operator[]は、境界チェックなしで指定された要素への参照を返します。

つまり、ベクトルが魔法のようにサイズ変更されたり、要素が存在することを保証するために他の操作を実行したりすることはありません。要素が存在しない場合、結果は未定義の動作です。つまり、何かが起こる可能性があります。実際には、多くの場合、プログラムは無効なメモリ位置にアクセスし、クラッシュを引き起こします。

上記は単なるvector<int>でも当てはまります。 vector<vector<int> >vector<vector<int> >の各要素はvector<int>です)を使用して問題を複合化しました。

あなたの関数は、実際には未定義のビヘイビアを呼び出す回数が少し息を吹いています。ステートメントnewMatrix[i][j] = m[i][j]でクラッシュすることがありますが、実際には未定義の動作の可能性があります。

(コードでチェックされていない)の値が0の場合、外部ループではm[i]は存在しません。 m.size()が0の場合、m[i]m.operator[](i))の評価は未定義の動作になります。

は基本的に、あなたはm[i]を評価する前にiが有効である任意のインデックスを確認し、[ALSO jm[i][j]を評価する前に、m[i]の有効な指標であることを確認する必要があります。そしてnewMatrixについても同様にします。あなたのコードはこれをまったく実行しません。あなたの機能のより正確なレンダリングが、事はある、あなたのコードが実際にベクトルがすでに提供する機能を再現している今

vector< vector<int> > resizeVector(vector< vector<int> > m) 
{ 
    vector< vector<int> > newMatrix; 
    int i,j; 

    newMatrix.resize(m.size()); // necessary to ensure we can access newMatrix[i] in the loop below 

    for (i = 0; i < m.size(); i++)  // ensure i is a valid index of m 
    { 
     // newMatrix[i].size() is still zero, so we need to resize for use in the inner loop 

     newMatrix[i].resize(m[i].size()); 

     for(j = 0; j < m[i].size(); j++) // ensure j is a valid index of m[i] 
     { 
      newMatrix[i][j] = m[i][j]; 
     } 
    } 
    return (newMatrix); 
} 

である(意図と仮定してmのコピーを作成することです)。そこで、我々は

vector< vector<int> > resizeVector(vector< vector<int> > m) 
{ 
     vector< vector<int> > newMatrix(m); 
     return newMatrix; 
} 

で非常に単純に関数の本体を交換することができ、さらには

vector< vector<int> > resizeVector(vector< vector<int> > m) 
{ 
     return m; 
} 

とこれはあなたの関数を意味します(私はそれを変更したとして)misnamedされる - それはサイズ変更されません。何でも実際には、呼び出し側がこの

x = resizeVector(y); 

が、それは単純にも、より効率的である

x = y; 

(ノー関数として、全くあなたの機能のない同じ効果を得ることができない場合は、以来、むしろ無意味ですコール、値渡しなどのコピーの作成はありません)。

関連する問題