dimanche 27 mars 2016

segmentation fault on ifstream variable declaration

I have some data contains user, item, time, result and I need to answer some queries. I create following data structure to store the information

map<user, map<pair<item, time>, result>>

The program will segmentation fault, unless I comment at least one line of followings. I try gdb to debug and the crash message says it crash at "ifstream in_file;"

if (count_item[itt2->first.first] == 1) { repeat_item.push_back(itt2->first.first); }

I can't understand why the declaration can make a program crash.

Bellow is all codes

#include <iostream>
#include <fstream>
#include <map>
#include <utility>
#include <string> 
#include <sstream>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;

int main() {
    ifstream in_file;
    in_file.open("/tmp2/KDDCUP2012/track1/rec_log_train.txt");
    int a[4];//a[0] = user, a[1] = item, a[2] = result, a[3] = time 
    typedef pair<int, int> item_time;
    typedef map<item_time, int> item_time_result;
    typedef map<int, item_time_result> user_item_time_result;
    user_item_time_result data_base;
    int count = 0;
    while (!in_file.eof()) {
        for (int i = 0; i < 4; i++) {
            in_file >> a[i];
        }
        if (data_base.find(a[0]) == data_base.end()) {//empty
            item_time_result* temp = new item_time_result();
            item_time* i_t = new item_time(a[1], a[3]);
            temp->emplace(*i_t, a[2]);
            data_base.emplace(a[0], *temp);         
        } else {
            auto it = data_base.find(a[0]);
            item_time* i_t = new item_time(a[1], a[3]);
            it->second.emplace(*i_t, a[2]);
        }
        count++;
        if (count % 100000 == 0)
            cerr << count << endl;
    }
    in_file.close();
    //data read into data_base from file
    //start query handling
    int query_number;
    cin >> query_number;
    cin.get();
    while (query_number--) {
        string query_type, query_parameter;
        queue<int> query_parameter_queue;
        getline(cin, query_type);
        getline(cin, query_parameter);
        istringstream iss(query_parameter);
        while (iss) {
            string sub;
            iss >> sub;
            if (sub.size())
                query_parameter_queue.push(stoi(sub));
        }
        if (query_type == "accept") {
            int user = query_parameter_queue.front();
            query_parameter_queue.pop();
            int item = query_parameter_queue.front();
            query_parameter_queue.pop();
            int mytime = query_parameter_queue.front();
            item_time i_t(item, mytime);
            auto it = data_base.find(user);
            if (it != data_base.end()) {
                auto itt = it->second.find(i_t);
                if (itt != it->second.end()) { 
                    cout << itt->second << endl;
                } else {
                    cout << 0 << endl;
                }
            } else {
                cout << 0 << endl;
            }
        } else if (query_type == "items") {
            int user1 = query_parameter_queue.front();
            query_parameter_queue.pop();
            int user2 = query_parameter_queue.front();
            int count_item[3000000] = {};
            vector<int> repeat_item;
            auto it1 = data_base.find(user1);
            if (it1 != data_base.end()) {
                for (auto itt1 = it1->second.begin(); itt1 != it1->second.end(); itt1++) {
                    count_item[itt1->first.first] = 1;
                }
            }

            auto it2 = data_base.find(user2);

            if (it2 != data_base.end()) {               
                for (auto itt2 = it2->second.begin(); itt2 != it2->second.end(); itt2++) {
                    if (count_item[itt2->first.first] == 1) {//if comment either this line or next line, the program won't crash
                        repeat_item.push_back(itt2->first.first);
                    }
                }
            }
            if (repeat_item.empty()) {
                cout << "EMPTY" << endl;
            } else {
                sort(repeat_item.begin(), repeat_item.end());
                for (auto it = repeat_item.begin(); it != repeat_item.end(); it++) {
                    cout << *it << endl;
                }
            }          
        } else if (query_type == "users") {

        } else if (query_type == "ratio") {

        } else if (query_type == "findtime_item") {

        } else {
            cout << "undefined query type\n";
        }           
    }
}

Aucun commentaire:

Enregistrer un commentaire