Stack overflow with no recursion? - c++

As far as I can see, my code has no recursion, but I am getting exception 0xC00000FD. According to Rider For Unreal Engine, it is happening in the main function. It's being encountered at the decompiled code
mov byte ptr [r11], 0x0
It was working fine, then suddenly when I ran it a second time, just to make sure it worked, it broke. It now gives that exception every time.
Here is my code:
// Language.cpp
#include <fstream>
#include <iostream>
#include <regex>
#include <stdexcept>
#include <string>
#include "Lexer/Lexer.h"
#include "Util/StrUtil.h"
int main(int argc, char* argv[])
{
std::string line, fileString;
std::ifstream file;
file.open(argv[1]);
if(file.is_open())
{
int lines = 0;
while(file.good())
{
if (lines > 10000)
{
std::cerr << "Whoa there, that file's a little long! Try compiling something less than 10,000 lines." << '\n';
return -1;
}
getline(file, line);
fileString += line + (char)10;
lines++;
}
}
fileString += (char)0x00;
std::string arr[10000];
int arrLength = StrUtil::split(fileString, "\n", arr);
Line lines[10000];
Lexer::lex(arr, arrLength, lines);
return 0;
}
// Lexer.cpp
#include "Lexer.h"
void Lexer::lex(std::string (&str)[10000], int length, Line (&lines)[10000])
{
for (int i = 0; i < length; i++)
{
}
}
// StrUtil.cpp
#include "StrUtil.h"
#include <stdexcept>
#include <string>
int StrUtil::split(std::string str, std::string delimiter, std::string (&out)[10000])
{
int pos = 0;
out[0] = str;
while (out[pos].find(delimiter) != std::string::npos)
{
const size_t found = out[pos].find(delimiter);
out[pos + 1] = out[pos].substr(found + delimiter.length());
out[pos] = out[pos].substr(0, found);
pos++;
}
return pos + 2;
}
For custom types, Line is an array of Tokens, which are just <TokenType, std::string> pairs.

As far as I can see, my code has no recursion
Indeed, there is no recursion in the shown code. Lack of recursion doesn't mean that you won't overflow the stack.
Stack overflow with no recursion?
Yes, this program is likely going to overflow the stack on some systems.
std::string arr[10000];
Typical size of std::string is 32 bytes (can vary greatly between language implementations). 10000 strings is 312 kiB. The execution stack on most desktop systems is one to few MiB. That one array is about the third of the memory that has to fit all of the automatic variables at the deepest stack frame of the program. It is very feasible that the remaning stack memory isn't enough for the rest of the program, especially considering you have another huge array of Line objects.
To fix the program, do not allocate massive variables such as this in automatic storage.

Related

c++ : char* invariably stores the word vector

This is although a code specific question but the output is quite bizarre.
I am aware of STL string etc. I was fooling around when I noticed something strange, and could not find a reason for it. :(
See the Two Codes below and the output.
[Code #1] (https://ideone.com/ydB8sQ)
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstdio>
using namespace std;
class str
{
private:
vector<char> A;
public:
str(const char *S) {
int sz = sizeof(S);
cerr << sz << endl;
for (int i = 0; i < sz; ++i) {
cout << S[i];
//A.push_back(S[i]); //!-- Comment --!//
}
}
};
int main(int argc, char const *argv[])
{
str A("");
return 0;
}
In this, An Empty String is passed and is printed. The Vector A does nothing but is relevant to this problem. In the first version, A is untouched, and the code prints garbage value. (see ideone O/P)
In this second version ( see A.push_back is now uncommented )
[Code #2] (https://ideone.com/PPHGZy)
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstdio>
using namespace std;
class str
{
private:
vector<char> A;
public:
str(const char *S) {
int sz = sizeof(S);
cerr << sz << endl;
for (int i = 0; i < sz; ++i) {
cout << S[i];
A.push_back(S[i]);
}
}
};
int main(int argc, char const *argv[])
{
str A("G");
return 0;
}
The Output is :
Gvector
This is across GCC / MinGW x64. This one never prints garbage value but always contains the word 'vector'.
Where is the char* in the function pointing to?
Why would 'vector' be there anyways?
Also, the size of char * is 8.
EDIT : This does not happen if it isn't wrapped around a 'class'.
The word 'vector' appears always. I supposed it was random garbage value but then how come ideone still has the same word in its memory?
The main problem in your code is in line int sz = sizeof(S);. sizeof(S) is always equal to sizeof(char *) which seems to be 8 on your system. sizeof gives you number of bytes for variable itself. If you want to know number of bytes in string to which your char pointer points, you should use strlen function instead.
You get that vector string in output randomly, as you are accessing memory which is not in allocated space. Accessing such memory is undefined behavior, so you get your undefined result.

C++ Array pointer-to-object error

I am having what seems to be a common issue however reading through the replies to the similar questions I can't find the solution to my issue at all as I have already done what they are suggesting such as making the variable an array. I have the following code:
#include "stdafx.h"
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <future>
using namespace std;
string eng2Str[4] = { "money", "politics", "RT", "#"};
int resArr[4];
int main()
{
engine2(eng2Str[4], resArr[4]);
system("Pause");
system("cls");
return 0;
}
void engine2(string &eng2Str, int &resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++) {
while (getline(fin, line)) {
if (line.find(eng2Str[i]) != string::npos) {
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
Before you mark as duplicate I have made sure of the following:
The array and variable I am trying to assign are both int
Its an array
The error is:
expression must have pointer-to-object type
The error is occurring at the "resArr[i] = fcount;" line and am not sure why as resArr is an int array and I am trying to assign it a value from another int variable. I am quite new to C++ so any help would be great as I am really stuck!
Thanks!
The problem is that you've declared your function to take a reference to a single string and int, not arrays. It should be:
void engine2(string *eng2Str, int *resArr)
or:
void engine2(string eng2Str[], int resArr[])
Then when you call it, you can give the array names as arguments:
engine2(eng2Str, resArr);
Another problem is the while loop in the function. This will read the entire file during the first iteration of the for() loop. Other iterations will not have anything to read, since it will be at the end of the file already. You could seek back to the beginning of the file, but a better way would be to rearrange the two loops so you just need to read the file once.
while (getline(fin, line)) {
for (int i = 0; i < 4; i++) {
if (line.find(eng2Str[i]) != string::npos) {
resArr[i]++;
}
}
}
I would suggest to use std::vector instead of pure C array.
In your code, there are more issues.
You are passing the fourth element of both arrays to the engine2 function.
From your definition of void engine2(string &eng2Str, int &resArr) you expect reference to a string (not array / vector) and an address / reference of int - you need to pass an pointer to the first element of resArr.
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <future>
using namespace std;
vector<string> eng2Str = { "money", "politics", "RT", "#" };
int resArr[4] = {};
void engine2(const vector<string>& eng2Str, int* resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++)
{
while (getline(fin, line))
{
if (line.find(eng2Str[i]) != string::npos)
{
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
int main()
{
engine2(eng2Str, resArr);
system("Pause");
system("cls");
return 0;
}

Atoi function while reading a .csv file C++

The execution of my code crashes when it gets to the "atoi" function, but I cannot understand why.
The code is supposed to read a matrix from a .csv file, considering:
- the first row (so till the first '\n') and saving each element (separated by a ',') in a vector of ints; - the rest of the matrix, by looking at each element and creating a specific object if the number read is 1 or 2.
I don't get any exception while debugging the program, it just crashes during the execution (and using the system ("PAUSE") I could figure out it was the atoi function which didn't work properly).
Can you help me understand what is going wrong?
Thank you very much.
Ps: I also attached all the libraries I'm loading... maybe it can help :)
#include <fstream>
#include <stdio.h>
#include <sstream>
#define nullptr 0
#include <string>
#include "classi.h"
#include <cstdlib>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
ifstream file("problem.csv");
unsigned int N = 0;
unsigned int M = 0;
char c; //modificato char * c;
unsigned int i=0,j=0, k=0, n_iter, j_temp =0;
std::vector<car> v_row;
std::vector<car> v_col_temp;
std::vector<int> iter; // location where I want to save the ints corresponding to the elements of the first row of the .csv file //
std::string iterazioni; //location where I want to save the first row as a string and then cut it into pieces (iteraz) and then convert (atoi --> iter)
std::string iteraz;
while(!file.eof()){
std::getline(file,iterazioni,'\n');
stringstream it(iterazioni);
while (it.good()) {
std::getline(it,iteraz, ',');
iter[k] = atoi(iteraz.c_str());
if(iter[k]<0){
cout<<"Errore: negative #of iterations"<<endl;
break;
}
iter.push_back(0);
k++;
}
iter.pop_back();
file.get(c);
if (c=='1'){
blue_car b(i,j);
if (v_col_temp[i].get_next() != nullptr)
v_col_temp[i].insert_tail(&b);
else
v_col_temp[i].insert_head(&b);
}
if (c=='2'){
red_car r(i,j);
if (v_row[i].get_next() != nullptr)
v_row[i].insert_tail(&r);
else
v_row[i].insert_head(&r);
}
if (c==',') {
j++;
if (i == 0)
j_temp++;
}
if (c=='\n'){
car p;
v_row.push_back(p);
v_col_temp.push_back(p);
i++;
if (j != j_temp) {
std ::cout<<"errore input non valido: numero righe/colonne non coerente"<<endl;
}
j=0;
}
else if ((c!='\n') && (c!=',') && (c!='0') && (c!='1') && (c!='2'))
std ::cout<<"errore input non valido"<<endl;
};
n_iter = k-1;
M=i;
N=j+1;
...
Your program crashes because you failed to initialize the contents of the iter vector.
std::vector<int> iter; // location where I want to save the ints corresponding to the elements of the first row of the .csv file //
You declare and construct this vector. The vector is empty at this point, and it has no elements.
At some point later:
iter[k] = atoi(iteraz.c_str());
The initial value of k is 0, so this attempts to assign the return value from atoi() to iter[0].
The problem is, of course, there is no iter[0]. The iter vector is still empty, at this point.
Additional comments, which is sadly true for at least 50% of these kinds of questions on stackoverflow.com:
1) "using namespace std"; is a bad practice, that should be avoided
2) Do not use system("pause") as well, as you referenced in your question.

Unclear Segmentation fault of using Boost Coroutine(1.55)?

I write a piece of code which will get a Segmentation fault. I am not sure whether it is a bug of Boost Coroutine or my code below:
#include <string>
#include <functional>
#include <vector>
#include <fstream>
#include <boost/coroutine/coroutine.hpp>
using namespace std;
template <class T>
using C = boost::coroutines::coroutine<T()>;
string foo(C<string>::caller_type & yield,
std::string fn, int cnt) {
std::ifstream f(fn);
// f.close();
int local_cnt = 0;
while(local_cnt < cnt) {
string l;
getline(f, l);
local_cnt ++;
yield(l);
}
f.close();
}
int main(int argc, char *argv[])
{
vector<C<string> > result;
for(int i = 0; i < 8192; ++i) {
C<string> obj(bind(foo, std::placeholders::_1, "test.txt", 3)); // line I
result.push_back(std::move(obj)); // line J
}
return 0;
}
test.txt is very large so it will never get the eof before segfault occurring. I use 1.55 of Boost and there are some observation:
seg-error occured in line I
If I delete or move f.close() before yield clause, seg-error disappeared.
If I delete line J in the code, seg-error disappeared.
If I use a smaller number in stead of 8192(say 512), seg-error disappeared.
What's the problem here?
"Too many open files" - you exceed the max number of open file descriptors
If I use a smaller number in stead of 8192(say 512), seg-error disappeared.
the seg fault will happen inside the ifstream (does not throw)
check ulimit -n
cat /proc/sys/fs/file-max
sysctl

"Segmentation Fault [Core Dumped]" while initializing 2d array of char dynamically [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I want to get an array of strings from user. I am getting the exception "Segmentation Fault [Core Dumped]" on runtime.
#include <iostream>
#include <iomanip>
#include <math.h>
#include <string.h>
using namespace std;
int main() {
long testCaseCount = 0;
cin >> testCaseCount;
char **testCases;
*testCases = new char[testCaseCount];
for(int i=0;i<testCaseCount;i++) {
cin >> testCases[i];
}
}
You're not allocating space for each string being read. The following are two ways to do what you're trying, the first being the mostly-C approach you seem to want to take, the second fully exploiting the standard library for all its glory.
Both of the following examples should result in the same test strings given the same input content. The first resizes with each new additional char arrival. Though it may seem overkill, it is actually simpler than maintaining a geometric growth algorithm.
That said, here is the code. I leave it to you to decide which of these is more prone to errors and bugs (and I just wrote both online, so there are bound to be bugs regardless).
The Hard Way
#include <iostream>
#include <cstdlib>
#include <cctype>
using namespace std;
int main()
{
unsigned int testCaseCount = 0;
char **testCases = NULL;
// read and validate we received a count greater than zero
if (cin >> testCaseCount && testCaseCount > 0)
{
// allocate + nullinitialize that many pointers
testCases = new char *[testCaseCount]();
for (unsigned int i = 0; i < testCaseCount && cin; ++i)
{
// skip leading whitespace
char ch;
while (cin.get(ch) && std::isspace(ch));
if (cin)
{
// read chars until whitespace or EOF. vsize
// represents the size of the allocated buffer
char *value = new char[1]();
size_t vsize = 1;
while (cin.get(ch) && !std::isspace(ch))
{
// allocate larger buffer
char *tmp = new char[vsize + 1];
// copy in old content to new buffer
std::copy(value, value + vsize, tmp);
std::swap(value, tmp);
// save new char and terminator
value[vsize - 1] = ch;
value[vsize++] = 0;
// delete old buffer
delete[] tmp;
}
// save accumulated value.
testCases[i] = value;
}
}
}
// show test cases
for (unsigned int i = 0; i < testCaseCount && testCases[i]; ++i)
std::cout << testCases[i] << '\n';
// cleanup
for (unsigned int i = 0; i < testCaseCount && testCases[i]; ++i)
delete[] testCases[i];
delete[] testCases;
return 0;
}
The Easy Way
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
int main()
{
unsigned int testCaseCount = 0;
std::vector<std::string> testCases;
if (cin >> testCaseCount)
{
std::string s;
while (testCaseCount-- && cin >> s)
testCases.emplace_back(s);
}
// show test cases
for (auto const& s : testCases)
std::cout << s << '\n';
return 0;
}
You have to write at least as
char **testCases = new char *;
*testCases = new char[testCaseCount];
Though it is not clear why you do not want to write simply as
char *testCases = new char[testCaseCount];
And do not forget to delete what was allocated with the operator new.
Take into account that it is not "an array of strings". It is simply an array of characters. If you want to get an array of strings you should at first decide what will be the maximum length of a string.
First you need to allocate space for the pointers to the first character of each string:
char** testCases = new char*[testCaseCount];
Then you'll need to allocate space for each string:
testCaseCount[i] = new char[maxStringLength];
cin >> testCaseCount[i];
However, this is dangerous-- cin won't do any bounds checking. You really should use std::string.
Getting Exception "Segmentation Fault [Core Dumped]" on runtime.
You have undefined behavior by dereferencing an undefined pointer in:
*testCases = new char[testCaseCount];
Objective: I want to get an array of strings from user
In c++ you use an std::string and an std::vector:
#include <iostream>
#include <string>
#include <vector>
int main() {
long testCaseCount = 0;
std::cin >> testCaseCount;
std::vector<std::string> testCases(testCaseCount);
for (auto& s : testCases)
std::cin >> s;
}
Live demo