Microsoft C++ exception: std::out_of_range error? - c++

I keep getting the following error:
Unhandled exception at 0x74BDD8A8 in FileName.exe: Microsoft C++ exception: std::out_of_range at memory location 0x004FA55C.
I've done some searching but I was not able to solve this problem. I did narrow it down to the fact that the out of range error is coming from my string fdata variable. Here is my code where error/exception occurs:
void MyClass::MyMethod10()
{
string fdata;
char num[100];
int i = 0,k=0;
unsigned int m,j=0;
inputFile.open("sec1.txt", ios::in);
inputFile >> fdata;
while (j<fdata.length())
{
while (fdata.at(j) != '+')
{
if (fdata.at(j) != '*' && j<fdata.length())
{
num[k] = fdata.at(j);
k++;
}
else
{
num[k] = '\0';
m = atoi(num);
//cout << m << endl;
MyMethod22(m);
k = 0;
}
j++;
}
MyMethod22(43);
j++;
}
inputFile.close();
outputFile.open("sec2.txt", ios::out);
while (i<index)
{
outputFile << (char)data[i];
i++;
}
outputFile.close();
CleanBuffer();
}
The sec1.txt file contains the following data
25750*23084*57475*15982*+57475*15982*+13364*15982*26260*+48840*32397*13364*15982*57475*11371*21876*+25197*
In the while() loop section my program is able to read the data correctly from the file. The problem/error/exception occurs at the point where my program takes in the last number from the file. I am guessing the problem is in the while() loop, but I am not able to figure out what's wrong. All I was able to do was to narrow down the error to string fdata being out of range after it reads the last number from the file. I was wondering if anyone can help me to solve this or suggest something which I might have missed?

The actual problem you have is here:
while (fdata.at(j) != '+')
{
...
j++;
}
Note that you increment j, and try to read j-th character before you check if j is in range. To fix it, change it like this:
while (j < fdata.size() && fdata.at(j) != '+')
{
...
j++;
}

Related

I have a text file with each line containing an integer. I want to open the text tile and count the number of integers in the file

void DataHousing::FileOpen() {
int count = 0;
// attempt to open the file with read permission
ifstream inputHandle("NumFile500.txt", ios::in);
if (inputHandle.is_open() == true) {
while (!inputHandle.eof()) {
count++;
}
inputHandle.close();
}
else {
cout << "error";
}
cout << count;
}
This is getting stuck in the while loop. But shouldn't the while loop end when it gets to the end of file? Also, I'm not even sure yet if it is counting correctly.
A fairly easy way to do this would be to use std::cin instead. Assuming that you want to count the number of integers in a file you can just use a while loop like so:
int readInt;
int count = 0;
while(std::cin >> readInt){
count++;
}
Then you just pass in the file as an argument parameter to your executable as so:
exec < filename
If you prefer to go through the route you're going then you can just replace your while loop condition with !inputHandle.eof() && std::getline(inputHandle, someStringHere) Then proceed to check if someStringHere is an int and increment your count if it is like so:
int count = 0;
std::string s;
ifstream inputHandle("NumFile500.txt", ios::in);
if (inputHandle.is_open() == true) {
while (!inputHandle.eof() && std::getline(inputHandle, s)) {
if(check to see if it's a number here)
count++;
}
inputHandle.close();
}

Cannot find bounds of current function (Code::Blocks) C++

I am using the latest version of Code::Blocks. I have a function that passes in a string and a vector. The function compiles with no errors. However, when I run the debugger, it immediately leads me to line 118 (which I have noted) and gives me trouble. The error that comes up says "Cannot find bounds of current function".
Here is the function, which takes in a line of code of a variable declaration (like "var c=0"), and gets the variable of it and adds its value to the vector, v, a struct with an int value and string name:
char get_variable_declaration(string line, vector<variable> &v)
{
string b;
variable t;
char d[0];
int counter = 0;
int a;
for (int i = 0; i<line.size(); i++) {
if (line[i] == 'r' && counter != 1) {
b[0] = line [i+2];
counter ++;
}
if (line[i] == '=') {
b[1]=line[i+1];
}
}
t.name = b[0];
d[0] = b[1];
a = atoi (d);
t.value = a;
v.push_back (t);
return b[0];
//This function will take in a line of code
//that is confirmed to have a variable declaration
//it will add the variable to the list of
//vectors
}
Here is when it is called:
bool read_code(string file_name, vector<funct> &my_functions, vector<variable> & v)
{
vector<string> code;
string s;
std::size_t found;
bool flag;
funct new_function;
ifstream in;
in.open(file_name.c_str());
if(in.is_open())
{
//read in file line by line and put it into a vector called code
while(in.peek()!=EOF)
{
getline(in,s);
code.push_back(s);
}
in.clear();
in.close();
//read through each line of the code, determine if it's a variable or function (definition or call)
//here it makes reference to functions (listed following this one) which will actually decompose the line
//for information
for(int i=0;i<code.size();i++)
{
//check if it's a variable declaration
found = code[i].find("var");
if(found!=std::string::npos) //its a variable declaration
get_variable_declaration(code[i], v); //ERROR CANNOT FIND..
//check if it's a function. it'll go in the list of functions
found = code[i].find("funct");
if (found!=std::string::npos) //that means it's a function
{
new_function.funct_name=get_function_name(code[i]);
new_function.commands.clear();
i+=2; //skip over the open curly brace
flag=false;
while(!flag)
{
found = code[i].find("}");
if(found==std::string::npos)
{
new_function.commands.push_back(code[i]);
i++;
}
else
{
my_functions.push_back(new_function);
flag=true;
}
}
}
}
return true;
}
else
{
cout << "Cannot locate this file" << endl;
return false;
}
}
Disclaimer: Yes, this is a homework assignment. No, I am not looking for anyone to finish this assignment for me. But, I am still mostly a novice at coding, in need of some assistance, so I ask if you know what is going on, please help me address this issue. Thanks!
Edit: I have gotten this to work on another compiler w/o the text file I am reading from. Not sure if this is a universal issue, or one that the other compiler just didn't pick up on.
Multiple problems with this section of code:
string b;
for (int i = 0; i<line.size(); i++) {
if (line[i] == 'r' && counter != 1) {
b[0] = line [i+2];
counter ++;
}
if (line[i] == '=') {
b[1]=line[i+1];
}
}
Problems:
If the last character in line is 'r', undefined behavior can occur.
If the next to last character in line is 'r', undefined behavior can occur.
If the last character in line is '=', undefined behavior occurs.
Both assignments to b[0] and b[1] is undefined behavior. The b string is empty.
There are also other instances of undefined behavior that have been noted in the comments, which I won't duplicate.
I found the problem. To correctly use atoi, you cannot use a specific character from a string or character array. If you declare a char a[3], and you want to use atoi, you must use it like int value = atoi(a) and not value = atoi(a[2]). If you do not do it this way, it will cause a runtime error.

segmentation fault in swap function

im busy writing a line of code for my study.
I already have gotten quite far on the assignment but i keep running into the same problem.
On the swap function i keep running into a segmentation fault when a character is inputted(word & word2) that is not in the main 'dictionary' string.
Could someone explain to me what is causing the problem and how i can solve it? Sorry if anything isnt clear, i've just started learning c++.
code where segmentation fault occures:
void swapWords(char **dict, char *word, char *word2)
{
int i;
int d;
int x;
int y;
char *tmp;
while (1){
for(i = 0; i < MAX_NUMBER_OF_WORDS; i++)
{
if(strcmp(word, dict[i]) != 0)
{
if(i == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.\n");
goto error;
}
}
else
{
x = i;
break;
}
}
for(d = 0; d < MAX_NUMBER_OF_WORDS; d++)
{
if(strcmp(word2, dict[d]) != 0)
{
if(d == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.\n");
goto error;
}
}
else
{
y = d;
break;
}
}
tmp = dict[x];
dict[x] = dict[y];
dict[y] = tmp;
error: break;
}
}
The entire code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#define MAX_NUMBER_OF_WORDS 10
void swapWords(char **dict, char *word, char *word2)
{
int i;
int d;
int x;
int y;
char *tmp;
while (1){
for(i = 0; i < MAX_NUMBER_OF_WORDS; i++)
{
if(strcmp(word, dict[i]) != 0)
{
if(i == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.\n");
goto error;
}
}
else
{
x = i;
break;
}
}
for(d = 0; d < MAX_NUMBER_OF_WORDS; d++)
{
if(strcmp(word2, dict[d]) != 0)
{
if(d == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.\n");
goto error;
}
}
else
{
y = d;
break;
}
}
tmp = dict[x];
dict[x] = dict[y];
dict[y] = tmp;
error: break;
}
}
void removeWord(char **dict, char *word)
{
int i;
int d;
for(i = 0; i < MAX_NUMBER_OF_WORDS; i++)
{
if(strcmp(dict[i], word) == 0)
{ dict[i] = NULL;
for(d = i+1; d < MAX_NUMBER_OF_WORDS; d++)
{ if(dict[d] == NULL)
{ dict[i] = dict[d-1];
dict[d-1] = NULL;
break;
}
}
break;
}
}
}
void printDict(char **dict)
{
int i = 0;
if(dict[0] == NULL)
{
printf("The dictionary is empty.\n");
}
else{
while (dict[i] != NULL)
{
printf("- %s\n", dict[i]);
i++;
}
}
}
void addWord(char **dict, char *word)
{
int d;
char *word1;
for(d = 0; d < MAX_NUMBER_OF_WORDS; d++)
{
if (dict[d] == NULL)
{
word1 = (char*) malloc(sizeof(char)*(strlen(word) + 1));
strcpy(word1, word);
dict[d] = word1;
break;
}
}
}
int numberOfWordsInDict(char **dict)
{
int i = 0;
int d;
for (d = 0; d < MAX_NUMBER_OF_WORDS; d++){
if(dict[d] != NULL)
{
i++;
}
}
return i;
}
int main()
{
char *dict[MAX_NUMBER_OF_WORDS] = {};
char word[36];
char word2[36];
char c;
int i;
while(printf("Command (a/p/r/s/q): "))
{
scanf(" %c", &c);
switch (c){
case 'p': printDict(dict);
break;
case 'a': printf("Enter a word: ");
scanf("%s", word);
addWord(dict, word);
break;
case 'n': i = numberOfWordsInDict(dict);
printf("%d\n", i);
break;
case 'r': printf("Remove a word: ");
scanf("%s", word);
removeWord(dict, word);
break;
case 's': printf("Swap two words:\n");
printf("Enter first word: ");
scanf("%s", word);
printf("Enter second word: ");
scanf("%s", word2);
swapWords(dict, word, word2);
break;
case 'q': return 0;
}
}
}
It will be most helpful to your studies as a student if you find the actual error yourself, though Marco and πάντα ῥεῖ may be right. However, here are a few things to think about, as this will definitely not be your last segfault problem as a programmer (I had at least 20 this month alone).
A segmentation fault is almost always caused by the code trying to modify or read memory that it doesn't have permission to read or modify. When the program starts, it is given a chunk of memory (RAM) to work with. For security reasons, no program is allowed to work with memory outside of that chunk. There are other limitations at play too.
As a general rule, if you try to read memory past the end of an array, you have a high risk of getting a segfault, or in other cases, garbled data. The official word on this actually comes from C, C++'s parent language, in that accessing past the end of an array causes "undefined behavior". Or, as it was once said on USENET, "it is legal for the compiler to make demons fly out of your nose". The behavior is totally unpredictable. Thankfully, that undefined behavior usually IS a segfault.
By the way, if you try to access an uninitialized array, similar weirdness can happen.
NOW, since you are accessing the elements of your array via a loop, another possible cause is that your loop is continuing beyond where you think it is. Sometimes it is helpful to modify your code so that the loop's iterator (i in your case) is printed out each iteration. This can help you catch if the loop is going beyond where it should.
In short, check...
Did I initialize all of my arrays before I tried to read or write
them?
Are my loops starting and stopping where I expected? Check for
"off-by-one" errors (i.e. starting at 1 instead of 0), infinite
loops (forgot to increment the iterator or the stop condition is
never true), and other logical errors.
Am I trying to read/write past the end of the array?
If I'm working with a C-string, did I forget the NULL terminator?
In addition to your debugger, which you should learn how to use well, tools like valgrind are instrumental in finding the cause of memory errors. Oftentimes, it can point you to the exact line of code where the segfault is occuring.
I had figured out myself the problem was in the strcmp. I know that figuring out a problem by myself is the best way to learn and I tried, but I just couldn't figure out why it was returning a seg fault. As this is my fifth assignment I'm only just getting to know how array's and pointers work. I assumed that the array was already initialized as 'NULL', as seen I was already comparing the pointer to 'NULL' in the addWord function. To assume this is ofcourse very stupid of me. I might not have figured the problem out by myself, yet it is still something I will not be forgetting anymore.
Most probably the segmentation fault happens here:
if(strcmp(word, dict[i]) != 0)
Infact it is quite likely that that i > becomes bigger than the size of your dict and if your dict has 3 elements and you try to access the 4th you are accessing an unknown area or ram and that causes a segmentation fault.
The solution is to make sure your for loop stops at the last element of the dictionary with the solution πάντα ῥεῖ has proposed in the above comment.

How can I exclude words with apostrophes when reading into a table of strings?

ifstream fin;
string temp;
fin.open("engldict.txt");
if(fin.is_open())
{
bool apos = false;
while(!fin.eof())
{
getline(fin, temp, '\n');
if(temp.length() > 2 && temp.length() < 7)
{
for(unsigned int i = 0; i < temp.length(); i++)
{
if(temp.c_str()[i] == '\'')
apos = true;
}
if(!apos)
dictionary.insert(temp);
}
}
}
This code gives me a runtime error: Unhandled exception at 0x00A50606 in Word Jumble.exe: 0xC0000005: Access violation reading location 0x00000014.
and throws me a break point at:
size_type size() const _NOEXCEPT
{ // return length of sequence
return (this->_Mysize);
}
within the xstring header.
This exception is thrown no matter what character I use, so long as it is present within the words I am reading in.
I am aware that it is probably a super simple fix, but I just really need another set of eyes to see it. Thanks in advance.

C++/CLI - URL Download to File

I'm not entirely familiar with how CLI works, but I have a general idea. I have a function that takes 2 System::String variables, and uses those to download a file from a webpage. As far as the download goes, it works fine, and the file shows up in my directory with the necessary content. However, it gives me the error
An unhandled exception of type 'System.AccessViolationException'
occurred in ParseLinks.exe
void downloadFile(System::String ^_URL, System::String ^_saveAs)
{
try
{
System::Net::WebClient ^webClient = gcnew System::Net::WebClient();
// Downloads the resource with the specified URI to a local file.
webClient->DownloadFile(_URL, _saveAs);
webClient->Dispose();
}
catch (System::Exception ^_e)
{
// Error
System::Console::WriteLine("Exception caught in process: {0}", _e);
}
}
I did some digging and output testing, and found out that the exe is hitting a break point somewhere in the text file, as the entire webpage did not save to the txt file.
Relevant code for that:
if (myFile.is_open()) //if file open
{
while (!myFile.eof()) //before end of file
{
getline(myFile, ln);
lines[count] = ln;
count++; //count total lines to set loop length for later parsing
//Error occurs somewhere in here
}
myFile.close();
}
else
cout<<"Error: Could not access file\n";
Brand New Error! :(
An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occurred in ParseLinks.exe
The code after the file -> line array loop
myFile.close(); //Close txt file
//Loop through lines
for (int i = 0; i < count; i++)
{
string temp = parseLinks(lines[i]); //parse links from each line
The function for that:
string parseLinks(string str)
{
const int len = str.length();
string link;
bool quotes = false, islink = false;
string compare[5] = {".htm",".html",".php",".asp",".pdf"};
//Parse all quoted text
for (int i = 0; i != len; i++)
{
//Change bool if quote found
if (str[i] == '"')
{
if (quotes == false)
quotes = true;
else
quotes = false;
}
//If bool true, and char is not a quote, add to link string
if (quotes == true && str[i] != '"')
link += str[i];
}
//Discard non-link text
for (int i = 0; i < 5; i++)
{
//Link check for links given array of path filetypes
if (link.compare((link.length() - compare[i].length()),compare[i].length(),compare[i]) == 0)
islink = true;
}
//Link check for links with no path filetype (.html, .php, etc.)
if (link.compare(0,7,"http://") == 0)
islink = true;
//If not a link, return empty string
if (islink == false)
link = "";
return link;
}
The error points to my large compare statement in this function. (Also, I'm clearly terrible at compressing my code)
You're using getline wrong, and possibly that's causing your error. The correct idiom is this:
std::string line;
while (std::getline(myFile, line))
{
// process `line`
}
There's no need to check myFile for openness separately.