结构向量的地址边界错误

时间:2019-02-02 00:58:47

标签: c++

我正在尝试建立结构的向量,并通过读取数据文件将数据添加到结构中。该代码正确解析数据文件,因为我能够打印出使用值songList[y],而不是songData[x].song。运行它时,总是出现错误SIGSEGV (Address boundary error)。我在做什么错了?

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

using namespace std;

struct Song{
    string song;
    string band;
    string minutes;
    string seconds;
    string album;
};

vector <Song> songData; // Vector the data will eventually end up

// MAIN FUNCTION

int main(){
    int x = 0, y = 0;
    vector <string> songList;
    // Open file
    ifstream infile;
    infile.open("songs.txt");
    // Add data to vector
    string tempLine;
    while(getline(infile, tempLine)){
        songData.push_back(Song());
        istringstream ss(tempLine);
        string temp;
    while(getline(ss, temp, ';')){
        songList.push_back(temp);
        if(x == 0){
                songData[x].song = songList[y];
                cout << "Song:\t" << songData[x].song << endl;
            }else if(x == 1){
                songData[x].band = songList[y];
                cout << "Band:\t" << songData[x].band << endl;
            }else if(x == 2){
                songData[x].minutes = songList[y];
                cout << "Min:\t" << songData[x].minutes << endl;
            }else if(x == 3){
                songData[x].seconds = songList[y];
                cout << "Sec:\t" << songData[x].seconds << endl;
            }else if(x == 4){
                songData[x].album = songList[y];
                cout << "Album:\t" << songData[x].album << endl;
            }else{
                cout << "Error!" << endl; // Will never run
        }
        x++;
        y++;
        if(x == 5){
            x = 0;
        }
    }
    }
    return 0;
}

这是数据文件(songs.txt):

Song 1;Band 1;Min 1;Sec 1;Album 1
Song 2;Band 2;Min 2;Sec 2;Album 2
Song 3;Band 3;Min 3;Sec 3;Album 3
Song 4;Band 4;Min 4;Sec 4;Album 4
Song 5;Band 5;Min 5;Sec 5;Album 5

1 个答案:

答案 0 :(得分:0)

分段错误的原因是您使用变量x的方式。

考虑一下:

while(getline(infile, tempLine)) {
    songData.push_back(Song()); // songData.size() = 1 after reading first line
    istringstream ss(tempLine);
    string temp;

现在考虑下面循环的第二次迭代(即读取Band 1):此时,x = 1songList.size() = 1

    while(getline(ss, temp, ';')) {
        songList.push_back(temp); // songList.size() = 2, after reading "Band 1"
        if(x == 0) {
            songData[x].song = songList[y];
            cout << "Song:\t" << songData[x].song << endl; 
        } else if(x == 1) {
            songData[x].band = songList[y]; // Undefined behaviour which may lead to Seg. Fault because songData.size() = 1 and you are trying to access 2nd element of songData.
            cout << "Band:\t" << songData[x].band << endl;
        }
        ...
        x++;
        y++;
        if(x == 5) {
            x = 0;
        }
    }
}

下面是更正的代码。我删除了向量songList,因为我认为它不是必需的。另外,我更改了变量xy的用法。

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

using namespace std;

struct Song{
    string song;
    string band;
    string minutes;
    string seconds;
    string album;
};

vector <Song> songData; // Vector the data will eventually end up

// MAIN FUNCTION

int main(){
    int x = 0, y = 0;
    // Open file
    ifstream infile;
    infile.open("songs.txt");
    // Add data to vector
    string tempLine;
    while (getline(cin, tempLine)) {
        songData.push_back(Song());
        istringstream ss(tempLine);
        string temp;

        while(getline(ss, temp, ';')){
            if(y == 0) {
                songData[x].song = temp;
                cout << "Song:\t" << songData[x].song << endl;
            } else if (y == 1) {
                songData[x].band = temp;
                cout << "Band:\t" << songData[x].band << endl;
            } else if (y == 2) {
                songData[x].minutes = temp;
                cout << "Min:\t" << songData[x].minutes << endl;
            } else if (y == 3) {
                songData[x].seconds = temp;
                cout << "Sec:\t" << songData[x].seconds << endl;
            } else if(y == 4) {
                songData[x].album = temp;
                cout << "Album:\t" << songData[x].album << endl;
            } else {
                cout << "Error!" << endl; // Will never run
            }
            y++;
            if(y == 5) {
                y = 0;
            }
        }

        x++;
    }
    return 0;
}