使用fstream时“0xC0000005:访问冲突”

时间:2011-06-21 18:54:14

标签: c++ access-violation fstream

我知道有很多关于访问违规的问题,但我已经阅读了很多,但似乎仍然无法解决这个问题。我正在将这段代码从java翻译成c ++,而且对c ++的熟悉程度要低得多,所以这段代码可能有点(也就是非常)不稳定。

我的代码在此行中断(在setup_next_buff_reader中):

this->buff_reader = new fstream(file_path,fstream::in|fstream::out);

它跳转到fstream中的close()函数。

我知道我处理指针,分配/解除分配内存等方面可能有问题,但我不知道在哪里。非常感谢任何帮助。

bool TabDelimitedSource::setup_next_buff_reader() {

        // Sets up the lucene analyzer and tries to load the next file in
        //    this->data_source_files, resetting counters/flags as needed

        this->current_source_file += 1;
        bool no_more_files = false; // assume we have no more files by default

        if(this->current_source_file < sizeof(this->data_source_files)){            
            const char* file_path = (this->data_source_files[this->current_source_file]).c_str();  
            cout << "File Path: " <<file_path <<"\n";
            this->buff_reader = new fstream(file_path,fstream::in|fstream::out);                
        }
        else{
                no_more_files = true;
        }

        return no_more_files; // let the caller know whether there was another file or not
}


TabDelimitedSource::TabDelimitedSource(){}

TabDelimitedSource::TabDelimitedSource(const char* dir_path) {
    // Load all of the files in the directory using the file name filter provided
    //fstream * data_source_dir = new fstream("path.txt");
    // NOTE: To change what files are loaded, use a different Filter here
    vector<string> files;
    this->getdir( dir_path,  files);
    this->data_source_files = files;
    open();
    cout << "Went through the TDSource constructor.\n";
}

void TabDelimitedSource::setColumnHoldingDoc(int column){
    // Allow the user to specify which column then want to extract
    this->column_holding_doc = column;
}

void TabDelimitedSource::open() {
    this->current_row = -1;
    this->current_source_file = -1;
    this->setup_next_buff_reader(); // setup first data source
}

void TabDelimitedSource::close() {
    try{
            this->buff_reader->close();
            this->buff_reader->clear();
    }
    catch (ifstream::failure e){
            ; // ignore this exception
    }
}

void TabDelimitedSource::reset(){
    this->close();
    this->open();
}

vector<string> TabDelimitedSource::getNext()  {
    // Returns the next document (a given cell) from the file(s)
    char row[256]; // Return NULL if no more documents/rows
    vector<string> document;

    try{
            this->buff_reader->getline(row, 256);
            cout <<"Row: "<< row << "\n";
    }catch (ifstream::failure e){
            ; // Ignore and fall through
    }

    if (buff_reader->eof()){
            this->current_row += 1;
            vector<string> cells;
            this->split(row, "\t", cells); // Split the row on tabs
            // Split the cell into individual words using the lucene analyzer
            try{
                string original_document = cells.at(this->column_holding_doc);  
            }catch (ifstream::failure e){
                    cout<<"Row " << this->current_row << " did not have column " << this->column_holding_doc;
            }
    }
    else{
            // We're at the end of the current file, try loading the next one
            bool no_more_files = this->setup_next_buff_reader();
            // If there was another file to load, recurse to get its first document
            if (!no_more_files){
                    // Don't waste time doing Array->ArrayList->Array conversion
                    return this->getNext();
            }           
    }

    // Return our arrayList as an array... there has to be a better way to do this
    vector<string> return_val ;
    if(!document.empty()){ // return NULL by default                
            for(int i=0; i<(int)document.size(); i++){
                    return_val.push_back(document[i]);
            }
    }

    return return_val;
}

void TabDelimitedSource::split(const string& str, const string& delim, vector<string>& result){
size_t start_pos = 0;
size_t match_pos;
size_t substr_length;

while((match_pos = str.find(delim, start_pos)) != string::npos){
    substr_length = match_pos - start_pos;

    if (substr_length > 0){
        result.push_back(str.substr(start_pos, substr_length));
    }
    start_pos = match_pos + delim.length();
}

substr_length = str.length() - start_pos;

if (substr_length > 0){
    result.push_back(str.substr(start_pos, substr_length));
}    
}

int TabDelimitedSource::getdir(string dir, vector<string> &files){
    DIR *dp;
    struct dirent *dirp;
    if((dp  = opendir(dir.c_str())) == NULL) {
        cout << "Error(" << errno << ") opening " << dir << endl;
        return errno;
    }

    while ((dirp = readdir(dp)) != NULL) {
        files.push_back((const char*)(dirp->d_name));
    }
    closedir(dp);
    return 0;
}

TabDelimitedSource::~TabDelimitedSource(){}

这是调用堆栈:

msvcp90d.dll!std::basic_filebuf<char,std::char_traits<char> >::close()  Line 232 + 0x3 bytes    C++
msvcp90d.dll!std::basic_fstream<char,std::char_traits<char> >::close()  Line 971 + 0xb bytes    C++
Testing.exe!TabDelimitedSource::close()  Line 98 + 0xe bytes    C++
Testing.exe!TabDelimitedSource::setup_next_buff_reader()  Line 26   C++
Testing.exe!TabDelimitedSource::open()  Line 94 C++
Testing.exe!TabDelimitedSource::TabDelimitedSource(const char * dir_path=0x09800fa8)  Line 76   C++
Testing.exe!Query::load_data_source(const char * data_path=0x09800fa8, std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_database="c:/Users/dfink.LISSARD2/Documents/Visual Studio 2008/Projects/Testing/jieddo.mdb", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_dbtable="jieddo_v2", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_field_id="report_id", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_field_text="summary", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_field_date="occured_when", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_filter="event_type='Explosive Hazard' ", int tab_delim_column=1)  Line 144 + 0x38 bytes   C++
Testing.exe!Query::model(const char * path=0x09800fa8, std::basic_string<char,std::char_traits<char>,std::allocator<char> > database="c:/Users/dfink.LISSARD2/Documents/Visual Studio 2008/Projects/Testing/jieddo.mdb", std::basic_string<char,std::char_traits<char>,std::allocator<char> > dbtable="jieddo_v2", std::basic_string<char,std::char_traits<char>,std::allocator<char> > field_id="report_id", std::basic_string<char,std::char_traits<char>,std::allocator<char> > field_text="summary", std::basic_string<char,std::char_traits<char>,std::allocator<char> > field_date="occured_when", std::basic_string<char,std::char_traits<char>,std::allocator<char> > filter="event_type='Explosive Hazard' ", int tab_delim_column=1)  Line 72 C++
Testing.exe!Query::Query(bool run_batch_job=true, std::basic_string<char,std::char_traits<char>,std::allocator<char> > datasource="tab-delimited-source", char * data_path=0x09800fa8, std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_database="c:/Users/dfink.LISSARD2/Documents/Visual Studio 2008/Projects/Testing/jieddo.mdb", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_dbtable="jieddo_v2", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_field_id="report_id", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_field_text="summary", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_field_date="occured_when", std::basic_string<char,std::char_traits<char>,std::allocator<char> > jdo_filter="event_type='Explosive Hazard' ", int tab_delim_column=1)  Line 55 C++
Testing.exe!main()  Line 209 + 0x1c3 bytes  C++
Testing.exe!__tmainCRTStartup()  Line 582 + 0x19 bytes  C
Testing.exe!mainCRTStartup()  Line 399  C
kernel32.dll!762e3677()     
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
ntdll.dll!77399f02()    
ntdll.dll!77399ed5()    

我调用TabDelimitedSource的地方:

bool Query::load_data_source(const char* data_path, string jdo_database, 
                    string jdo_dbtable, string jdo_field_id,
                    string jdo_field_text, string jdo_field_date,
                    string jdo_filter, int tab_delim_column){
    // Attempts to load the data source (to this.ds) based on the datasource name
    // NOTE:  This will write over the old data source if it exists!
    // data_path:       Where the source files are located
    // jdo_*:           Argument specific to Jieddo data source
    // tab_delim_colum: Which column to extract from a tab delimited source file
    bool load_successful = true;
    try{
            if (this->datasource.compare("tab-delimited-source") == 0) {
                    this->ds = new TabDelimitedSource(data_path);
                    this->ds->setColumnHoldingDoc(tab_delim_column);
                    string pref_text_analyzer;
                    this->ds->setColumnHoldingDoc(tab_delim_column);
            } 
            else {                      
                    load_successful = false;
            }
    }
    catch(ifstream::failure e){
            cout<<"FAIL."<<"n";
            load_successful = false;
    }
    return load_successful;
}
编辑:对不起,我忘记了我添加了两行代码(我把它们拿回来了)。实际上代码确实在上面提到的同一行中断了,但它在解锁函数中进入了mlock.h。

1 个答案:

答案 0 :(得分:1)

假设data_source_files是字符串的向量,这个测试

if(this->current_source_file < sizeof(this->data_source_files)){  

检查当前索引是否小于std :: vector对象中的字节数,而不是它是否小于向量中包含的字符串数。那将是

data_source_files.size()

这可能导致超出范围的访问。