2015-01-17 33 views
1

從指針向量中我重載了operator - =()來移除元素(指針是唯一的,所以不需要刪除所有的事件,循環可以在指針被擦除後終止):從矢量擦除後重復的指針

Rooms& Rooms::operator-=(Course *c) { 
    for (Iter i = rooms.begin(); i != rooms.end(); ++i) { 
     if (**i == *c) { 
      *i = NULL; 
      i = rooms.erase(i); 
      break; 
     } 
    } 
    return *this; 
} 

問題是,在應用到向量後,我得到了向量的最後一個元素的重複指針。之前:

------------------------------------------------------------------- 
| POL | CAE | RUS | ENG | BUS | JPY |  |  |  |  |  | 
| G 1 | G 1 | G 2 | G 2 | G 2 | G 2 |  |  |  |  |  | 
| 9 | 9 | 10 | 10 | 10 | 10 |  |  |  |  |  | 

去除ENG &公交車經過:

------------------------------------------------------------------- 
| POL | CAE | RUS | JPY | JPY | JPY |  |  |  |  |  | 
| G 1 | G 1 | G 2 | G 2 | G 2 | G 2 |  |  |  |  |  | 
| 9 | 9 | 10 | 10 | 10 | 10 |  |  |  |  |  | 

什麼應該改爲真正得到結果爲:

------------------------------------------------------------------- 
| POL | CAE | RUS | JPY |  |  |  |  |  |  |  | 
| G 1 | G 1 | G 2 | G 2 |  |  |  |  |  |  |  | 
| 9 | 9 | 10 | 10 |  |  |  |  |  |  |  | 

任何幫助將不勝感激。

編輯:

我的打印功能如下:

std::ostream& operator<<(std::ostream& out, const Rooms& rs) { 
    std::vector<std::string> output(3); 
    std::ostringstream temp; 
    for (int i = 0; i < rs.rooms.capacity(); ++i) { 
     if (rs.rooms[i]) { 
      temp << "| " << rs.rooms[i]->getCode() << " "; 
      output[0] += temp.str(); 
      temp.str(""); 
      temp << "| G" << std::setw(CODE_LENGTH - 1) 
       << rs.rooms[i]->getGroup() << " "; 
      output[1] += temp.str(); 
      temp.str(""); 
      temp << "| " << std::setw(CODE_LENGTH) 
       << rs.rooms[i]->getSize() << " "; 
      output[2] += temp.str(); 
      temp.str(""); 
     } else { 
      output[0] += "|  "; 
      output[1] += "|  "; 
      output[2] += "|  "; 
     } 
    } 
    output[0] += "|"; 
    output[1] += "|"; 
    output[2] += "|"; 
    out << printHorizont(rs.size) << output[0] << std::endl 
     << output[1] << std::endl << output[2] << std::endl; 
    return out; 
} 

看起來很複雜,但無法找到它的打印方式,我想的更好的方法。

+1

爲什麼這樣:'我='rooms.erase(i); ? – Hacketo

+2

@Hacketo被擦除的迭代器失效。 'erase'返回一個有效的迭代器到過去被擦除的元素。 OP:如果兩個可擦除元素彼此直接出現,此代碼將跳過元素,但會縮短向量。在所有這些之後使用矢量的代碼是否可能不檢查改變的長度? – Wintermute

+0

@Hacketo否則在打印結果時出現分段錯誤。在打印功能中,我使用房間[i]來訪問元素。 –

回答

1

operator<<()

for (int i = 0; i < rs.rooms.capacity(); ++i) { 

對於rs.rooms.size() <= i < rs.rooms.capacity(),基本上rs.rooms[i]是非法的。

使用迭代器遍歷向量,你永遠不會犯這樣的錯誤。如果你真的需要打印那些「空白空間」,你可以寫成:

for (int i = 0; i < rs.rooms.capacity(); ++i) { 
    if (i < rs.rooms.size() && rs.rooms[i]) { 
     // access rs.rooms[i] 
    } else { 
     // print empty placeholder 
    } 
} 
+1

這是說錯誤出現在您的打印程序中,而不是您的操作員 - =代碼,將打印程序中的capacity()更改爲size()。 –

+0

感謝發佈這個,我有一個問題,你。由於我需要打印空白空間,迭代器會在最後一個非空項目之後結束,還是在容量給出的最後一個元素之後結束? –

+0

迭代器在最後一個邏輯上非空的項目之後結束。 – timrau