开发者

"0xC0000005: Access violation" While using fstream

开发者 https://www.devze.com 2023-03-14 06:56 出处:网络
I know there are quite a few questions concerning access violations, but I have read a lot and still can\'t seem to crack this one. I\'m translating this code from java to c++ and am far less experien

I know there are quite a few questions concerning access violations, but I have read a lot and still can't seem to crack this one. I'm translating this code from java to c++ and am far less experienced with c++, so this code may be a bit (aka very) wonky.

My code breaks at this line (in setup_next_buff_reader):

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

And it jumps into the close() function in fstream.

I understand that there is probably something wrong with how I'm handling pointers, allocating/de-allocating memory, etc. but I don't know where. Any help on this is greatly appreciated.

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(){}

Here is the call stack:

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()    

The place where I am calling TabDelimitedSource:

bool Query::load_data_source(const char* data_path, string jdo_database, 
                    string jdo_dbtable, string jdo_field_id,
                    string jdo_f开发者_如何学JAVAield_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;
}

EDIT: Sorry, I forgot that I had added in two lines of code (I took them back out). The code does in fact break at the same line as mentioned above, but it steps into mlock.h, in the unlock function.


Assuming that data_source_files is a vector of strings, this test

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

checks if the current index is smaller than the number of bytes in a std::vector object, not if it is less than the number of strings contained in the vector. That would be

data_source_files.size()

This is likely to cause an out-of-range access.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号