2016-11-11 66 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

您的支票是錯誤的。相反,它應該是

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

您將分配到新的newMatrix而不先設置它的大小。它將默認爲空,並且任何嘗試分配給它都會導致未定義的行爲。

由於您不通過一個新的大小,很難確切知道你要完成什麼。這就是爲什麼我沒有更明確的建議如何解決它。

1

除了@Saurav發佈的內容,newMatrix爲空,因此您無法將值分配給newMatrix[i][j]。您可以通過給定大小初始化向量解決這個問題:

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循環,我們初始化newMatrix之前已經在其內部m.size()很多空向量(矢量是空的,由於其默認的構造函數)。在外部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

vector s operator[]返回對指定元素的引用,無邊界檢查。

這意味着它不會神奇地調整矢量大小或執行任何其他操作來確保元素存在。如果元素不存在,結果是未定義的行爲 - 這意味着任何事情都可能發生。實際上,它通常會導致程序訪問無效的內存位置,從而導致崩潰。

即使是簡單的vector<int>也是如此。通過使用vector<vector<int> >vector<vector<int> >的每個元素是vector<int>),您的問題就複雜化了。

您的函數實際上可能會調用未定義行爲的次數令人驚歎。您碰巧在語句newMatrix[i][j] = m[i][j]上發生崩潰,但未定義行爲的可能性實際上在此之前發生。

在外部循環中,如果m.size()(您的代碼未檢查)的值爲零,則m[i]將不存在。如果m.size()爲零,則會導致m[i](如m.operator[](i))的評估具有未定義的行爲。

本質上講,你需要確保任何索引i有效評估m[i]前,然後還要確保j是評估m[i][j]之前的m[i]有效的索引。然後爲newMatrix做同樣的事情。你的代碼根本就沒有這個功能。你的函數的更正確的渲染(假設的意圖是建立m副本)是

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); 
} 

現在的事情是,你的代碼實際上是再造功能,載體提供了。所以,我們可以很簡單地用

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; 
} 

這意味着你的函數替換函數體(因爲我已經修改了它)是名不副實的 - 它不調整任何東西。事實上,這是因爲毫無意義,如果來電者這

x = resizeVector(y); 

它可以實現沒有你的功能相同的效果都沒有,只是作爲

x = y; 

這也是更有效的(無功能調用,不創建副本以通過值傳遞等)。

相關問題