簡體   English   中英

矢量push_back崩潰

[英]vector push_back crashing

我有以下結構。

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>

struct station {
    std::string id;
    std::string code;
    std::string station_name;
    station(std::vector<std::string> &in) : id(in[0]), code(in[1]), 
                                            station_name(in[2]) {}
    station(): id (""), code (""), station_name(""){}

    bool operator<( const station& rhs ) const {
        return this->station_name < rhs.station_name;   
    }
};
int main(int argc, char **argv) {    
    std::ifstream ifs(argv[1]);
    if ( ifs.peek() == EOF )  {
        exit ( 1 );
    }
    // Read the input file and update the database
    std::string line;
    station prev, current;
    std::set<station> my_set;
    while( ifs.good()&& std::getline(ifs,line) ) {
        std::stringstream  lineStream(line);
        std::string        token;
        std::vector<std::string> input;        
        while(std::getline(lineStream,token,',')) {
            input.push_back(token);
        }
        station st(input);
        my_set.insert(st);

    }
}

我正在閱讀一個文件,其中包含以下格式ID,Station Code,Station Name railway stations相關信息

我正在逐行讀取此文件並創建一個station對象,然后將其推送到std::set<station>

經過一段時間后,它會在閱讀21448行之后21448 我有大約403523

這里有什么問題。

此程序在Linux上正常運行,但在Windows上無法運行

我得到debug assertion failed

采用數組的構造函數讓我很擔心。

編輯

根據更新的問題:

問題是采用向量的構造函數。
您正在訪問元素而不檢查它們是否存在。

因此,如果任何輸入行是壞的(即並非所有值都存在),那么向量將不會像所需的那樣大並導致未定義的行為。

如果您更改這些行:

while(std::getline(lineStream,token,',')) {
            input.push_back(token);
        }

成:

std::getline(linestream, id,   ',');
std::getline(linestream, code, ',');
std::getline(linestream, name, ',');

然后使用這些參數調用工作站構造函數(就像在OO代碼中一樣好)。 然后你就不會看到崩潰了。 一些錯誤檢查也很好。

注意:

while( ifs.good()&& std::getline(ifs,line) ) {

這里沒有必要檢查good()。 如果流未處於良好狀態,則getline()將不執行任何操作。 流的轉換(getline()的返回值)到bool也檢查狀態是否流有效進一步讀取,如果不是則將轉換為false(最終)。

// This is more idiomatic.
while(std::getline(ifs,line) ) {

原版的

嘗試這個:

struct station
{
    std::string id;
    std::string code;
    std::string station_name;
    friend std::istream& operator>>(std::istream& stream, station& data)
    {
        std::string  line;
        std::getline(stream, line);

        std::stringstream  linestream(line);
        std::getline(linestream, data.id, ',');
        std::getline(linestream, data.code, ',');
        std::getline(linestream, data.station_name);

        return stream;
    }
};

int main()
{
    std::ifstream   file("station.txt");
    std::vector<station>  stations;

    std::copy(std::istream_iterator<station>(file),
              std::istream_iterator<station>(),
              std::back_inserter(stations)
             );
}

這是了解一些調試技術的方便之處。 在你創建一個新station ,我會提出一個斷言:

assert(station_init_vector.size() >= 3);

這可以確保您不訪問不存在的矢量元素。

另一個工具是使用vector成員at()而不是operator [] ,它執行運行時索引檢查並將為越界索引拋出異常:

station(std::vector<std::string> &in) : id(in.at(0)), code(in.at(1)),
                                        station_name(in.at(2)) {}

您的輸入文件在哪個平台上創建? C ++運行時環境應該決定什么是您的平台的最佳行結束約定。 因此可能存在一些問題,但這並不能解釋為什么程序會等到21448行崩潰。

而且你的錯誤不足以提供足夠的信息。 通常當斷言失敗時,它會顯示失敗的位置。 在你的情況下,似乎它可能在std :: vector中失敗。 嘗試在構造函數中使用at()替換[]運算符。 當您嘗試訪問無效索引時,它會拋出超出范圍的異常。

最后,正如其他人已經指出的那樣,如果只有三個參數,將向量傳遞給構造函數並不是一個好主意。 它不僅可能產生難以捕獲的錯誤,而且還在while循環的每次迭代中為額外的構造函數和析構函數付出代價。 希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM