简体   繁体   中英

Crash while reading a File in C++

I want to search a particular word in a file & return a result as to whether that word exists in the file or not. I have created a function which does this. But while returning the program is crashing. Here is the code:

bool FindMyWord(const char *fileName)
{
    ifstream myFile (fileName);
    if(!myFile)
        return false;

    string wordSearch = "MyWord";
    string endSearch = "LastWord";
    bool result;
    while(1)
    {
        char read[20];
        myFile.getline(read, 1000, '\n');
        string line(read, read+20);
        if(line.find(wordSearch) != string::npos)
        {
            result = true;
            break; //comes here after looping about 10 times
        }
        if(line.find(endSearch) != string::npos)
        {
            result = false;
            break;
        }
    }
    myFile.close();
    return result;
} // <- crash when F10 is pressed after this

In VS2010 while debugging I find that the crash is happening after executing " return result; " in second last line of the function ie when the yellow cursor is for the last closing bracket of function. I am getting a message

A buffer overrun has occurred in myApp.exe which has corrupted the program's internal
state. Press Break to debug the program or Continue to terminate the program.

What is this error? I am calling the function like this :

bool result = FindMyWord("myFileName.stp");

UPDATE : Each line has varying no of characters & they are > 20. I want to read the 1st 20 characters & if the word does not exist in those characters then I want to jump to the next line. Initially I had used myFile.getline(read, 20, '\\n'); But after the 1st loop every subsequent looping resulted in NULL being passed to read. So I made it to read 1000 because before reading 1000 chars it would find '\\n' & go to next line. A better mechanism of achieving the same would be very helpful.

Why not use a std::string instead of a fixed length buffer?

bool FindMyWord(const char *fileName)
{
    std::ifstream myFile (fileName);
    if(!myFile) {
        return false;
    }

    std::string wordSearch = "MyWord";
    std::string endSearch = "LastWord";
    bool result;
    std::string line;
    while(std::getline(myFile, line))
    {
        if(line.find(wordSearch) != std::string::npos)
        {
            result = true;
            break; //comes here after looping about 10 times
        }
        if(line.find(endSearch) != std::string::npos)
        {
            result = false;
            break;
        }
    }
    myFile.close();
    return result;
} 

Buffer overflows have been responsible for far too many security problems. Just don't use fixed length buffers!

This is also slightly more correct, as it checks for errors on the stream.

PS I hate using namespace std !

myFile.getline(read, 1000, '\\n'); will read up to 1000 bytes into memory starting at address read . read is a 20 byte stack buffer so you risk writing beyond the end of your allocated memory. The effects of doing this are undefined but a crash is very likely.

To fix this, you should pass the size of the read buffer into getline ;

myFile.getline(read, sizeof(read), '\n');

(Note that sizeof(read) only works for a stack buffer. If read was allocated on the heap, sizeof would only tell you the size of the pointer rather than the allocated memory it points to.)

Until you can get the code working, forget about char[] . (As others have pointed out, you have a buffer overrun. Very easy to do with any C style array as a local variable.) Since you're looking for words, the initial code can be something as simple as:

std::string word;
while ( myFile >> word && word != "MyWord" && word != "LastWord" ) {
}
return word == "MyWord";

This can certainly be made faster, but if "LastWord" isn't very far into the file, it might not be necessary. (BYW: it's generally not necessary to close a file used in input. The destructor will take care of that, and since you've checked the status after each input anyway, there's no more error checking to worry about.)

One place I can think of in above code causing buffer over run is:

myFile.getline(read, 1000, '\\n');

Since 'read' is a buffer having space for 20 characters, it can not accomodate if file got a line bigger than that.

Also, please do eof check. I would suggest something like this:


bool FindMyWord(const char *fileName)
{
    if(!myFile)
        return false;

ifstream myFile (fileName);

const char* wordSearch = "MyWord";
const char* endSearch  = "LastWord";
bool result = false;
string line;

while(std::getline(myFile, line))
{
    if(line.find(wordSearch, 0, 20) != string::npos)
    {
        result = true;
        break; //comes here after looping about 10 times
    }

    if(line.find(endSearch, 0, 20) != string::npos)
    {
        result = false;
        break;
    }
}

myFile.close();
return result;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM