Program crashes with message "terminate called recursively" without throwing any exception [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was making a simple C++ program using CTable - my custom class. CTable contains a pointer to an array of int, which can be resized and manipulated with CTable methods.
Here's a short snippet:
class CTable
{
private:
int *table; //pointer to the table
int length; //length of the table
///...etc
public:
int SetLength(int length); //returns -1 on failure
int SetValueAt(int index, int value); //returns -1 on failure
///...etc
CTable& operator+=(CTable &other) //combine 2 CTables together
{
int oldLength = length;
SetLength(length+other.GetLength());
for(int i=oldLength;i<length;i++)
{
SetValueAt(i,other.GetValueAt(i-oldLength));
}
return *this;
}
};
I also have another function that I use to split user input into words:
vector<string>* splitString(string sentence, char delim)
{
vector<string> *res = new vector<string>();
stringstream ss;
ss.str(sentence);
string word;
while (getline(ss,word,delim))
{
res->push_back(word);
}
return res;
}
It is important to note that all the methods presented here seem to work fine on their own, i.e. when I test them individually.
As you can see I have also overloaded the += operator. The problem is that whenever I use this operator, the next user input crashes the program when the splitString() function is called. The program crashes with the sole error message "terminate called recursively". No exceptions is thrown, nothing. Only an error code 0xC0000005
I can't really show you the entire code because the program got pretty big, currently about 1000 lines of code. I try to fix this program for hours and I have no idea what's going on. Any help is greatly appreciated !

The windows error code 0xC0000005 means STATUS_ACCESS_VIOLATION. This is typically caused by problem with pointers, out of bound array accesses, memory corruption and other serious issues.
The splitString() function looks ok, so it certainly not causes by itself the kind of behavior you're describing.
The operator+=() looks more suspicious. The code itself seems ok, but it makes assumptions that SetLength() changes the length, reallocates the pointer, and copies all the existing values, all without any problem. Note by the way that this code doesn't handle special case such as doing += on one self.
Unfortunately, the signature of this function is int SetLength(int length);. So the name of the parameter hides the name of the member length, which could cause some serious mismatches that could lead to buffer overflows or unchanged member length (unless you use this->length and length to make the difference between the two).
Finally, you are using raw pointers instead of smart pointers. So you must ensure the rule of 3. If you don't, you will end-up with shallow copies which could also lead to UB (when one of the object releases the memory that it's copy is still using).

Related

Why does the data still exist after I delete the space of the array? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 months ago.
Improve this question
Today, I found a small problem when creating dynamic arrays.
I use the resize () function to change the size of the array. In the resize () function, I created a temporary array "newData", and then I assigned it the new size I wanted. After assigning the value of the initial array "Data" to it, I set
Data=newData;
At this time, the task of the resize () function has been completed. Before exiting the function, I had a whim and deleted the space of "newData" by
delete [] newData;
After that, when I output the value of Data [2], I can still output the value.
Now I'm a little confused. "Data" and "newData" should be pointers, right? When I use the statement "Data=newData;", what "Data" points to should become the address space that "newData" points to. If I delete the address space of "newData", shouldn't the space corresponding to "Data" also disappear? Why can I continue to output values?
The following is the complete code
#include<iostream>
using namespace std;
int Length = 0;
int* Data;
void resize(int,int *);
int main()
{
Data = new int[5];//This is the space I allocated for the initial array
for (int i = 0; i < 5; i++)
Data[i] = i;
Length = 5;//There are five data in the initial array
int newLength = 10;//I started distributing new sizes to the initial array
resize(newLength,Data);
cout << Data[2];//The output is still 2
}
void resize(int newLength,int *Data)
{
int* newData = new int[newLength];//A temporary array
for (int i = 0; i <Length; i++)//Move the value of the original array to the temporary array
{
newData[i] = Data[i];
}
Data = newData;
delete[] newData;//Delete the space where the temporary array is located
}
You (try to¹) access deleted space; that's what is called undefined behaviour in C++: Anything might happen. There might be the original values, the might be some other data you worked on put there, there might be the value 0xdeadcafe all over the place, your program might crash or cause a fire, delete all files or give an attacker access.
It's undefined, and you found one of the things that might happen.
¹ From your question, that was your intent. Luckily, you messed up your resize function prototype, and pass in the Data pointer by value, not by reference, so that your Data = newData; doesn't do anything outside your function. That together with the global variables on top of your files: Maybe revisit what a function is and what scope and pass-by-reference mean!
Generally, you're a C++ beginner: cool! That's a good path to be on.
Maybe do less with new and delete. It's been a while since I used these two, they're becoming a rare pattern in modern C++! C++ can very well (for the most part) be written without these, completely, by using other methods, where your memory allocation and deallocation are linked to objects' lifetimes. And that's way less error-prone, and honestly, easier to understand.
For example, in your use case, instead of your Data, newData, new and delete handling, you could have said std::vector<int> Data(Length);, have put the values in exactly as you did, and then just called Data.resize(newLength);. No need for manually knowing where to delete your memory!
I'm not sure why you're doing this, but you're declaring your variables globally. That's a bad idea from start to finish, so, um, just don't do that: Declare variables in the scope you need them, which would be your main function. Maybe someone who has had a very early 1970's copy of some C book confused obsolete C with the C++ you should be taught? I don't know. Global variables are generally a bad idea.

How Integers initialize in C++? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
#include <iostream>
#include <math.h>
using namespace std;
class ip{
private:
string ip;
int result[8];
int sum;
public:
void input(){
/* cout<<"Enter First 8 Binary in Ip address: ";
cin>>ip;
for(int i=0,j=7;i<8 ,j>=0;++i,--j){
if(ip[i]=='1'){
result[i]=pow(2,j);
}else if(ip[i]=='0'){
result[i]=0;
}
}
for(int i=1 ; i<8 ; ++i){
sum=sum+result[i];
} */
cout<<sum<<"\n";
}
};
int main() {
ip convert;
convert.input();
return 0;
}
I was getting some problem while running this code then I understood the problem is with integer initialization...
please help me as I'm getting unwanted output
after running this code my output is: 131
I expected '0' as output
why is it so
You're right, one problem is that you don't initialise sum to zero. Also int i = 1 should surely be int i = 0.
sum=0;
for(int i=0 ; i<8 ; ++i){
sum=sum+result[i];
There are lots of other problems with the code including unnecessary use of a class, unnecessary use of class variables, unnecessary use of floating point functions, unnecessary use of temporary array etc. etc. This program could be much simpler.
In C++, Automatic storage duration integer variables are not initialized to any particular value, and will contain whatever garbage bit pattern that happens to already be in those memory locations. From the perspective of the language standard, the value of the variable is indeterminate, and using it leads to undefined behavior. If you had defined it as a static variable, it would be auto-initialized to 0 in C++.
Most likely your compiler will also throw a warning if you try to use a uninitialized variable.
In GCC, you will see the warning if you compile with below flag:
-Wuninitialized
Warn if an automatic variable is used without first being initialized or if a variable may be clobbered by a setjmp call. In C++, warn if a non-static reference or non-static const member appears in a class without constructors.
Update based on Peter's comment:
In the above case, the code creates an automatic storage duration object of that class type. However, since you just declare an object of type ip as ip convert and you don't have your own constructor which initializes class objects' member values, compiler's default constructor will be called. Most compilers (if not all) will not initialize member values for you and hence you see an output corresponding to the bit pattern present in the memory locations where the object got created.

file handling I/O c++ error

this is the code which i am trying to run.The compiler shows some warning that the variable 'p' may be possible to be used uninitialized.
And ..on running it has a problem ..i will show..below.
please correct me and explain .
Thank you.
execution of code
*
code
that error is that..the first two elements of the character array being output are somewhat messed up!!!*
#include<bits/stdc++.h>
using namespace std;
class file{
public:int a;
char* name;
public:
file(int x,char* b):a(x){name=b;}
void printfile(){cout<<a<<" "<<name<<endl;}
};
int main(){
char *p;
int x=10;
cout<<"enter a name"<<endl;
cin>>p;
file k(x,p);
ofstream f("file",ios::out|ios::binary);
f.write((char*)&k,sizeof(class file));
f.close();
ifstream of("file",ios::in|ios::binary);
file o(0,'\0');
of.read((char*)&o,sizeof(class file));
o.printfile();
of.close();
return 1;
}
You have p as some pointer. Who is going to allocate the memory that pointer points to?
In C it is almost always the responsibility of the caller to allocate any buffers before the call.
If you don't want to, then use a std::string instead.
First of all I would advise you to read some basic manual about the c++ pointers and memory handling so you will better understand the source of the problem.
There are two major problems in your code.
The first is that you are creating a pointer which is not connected to any allocated memory. In simple words you are asking to access a memory address without asking the system to reserve it for you.
Additionally, in that memory location there can already be stored any bit configuration. The initialization of a variable is the task of giving a chunk of memory some data which have a meaningful interpretation. I'm not even sure what the in-stream operator of char* is supposed to do in this particular case. He is probably appending your characters after the last one which is not a 0 or an end of line.

Queries on a string [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
It's a B problem in codeforces
http://www.codeforces.com/problemset/problem/598/B
and i submit this code, but i get Wrong Answer.
It's brute force nothing special, but iam new at problem solving.
#include <iostream>
#include<string>
using namespace std;
int main()
{
char x[10000];
scanf_s("%s",x);
int num;
scanf_s("%d",&num);
int *l = new int[num];
int *r = new int[num];
int *k = new int[num];
for(int i =0;i<num;i++)
{
scanf_s("%d,%d,$d",&l[i],&r[i],&k[i]);
}
char temp;
for(int i =0; i<num;i++)
{
for (int j =0;j<k[i];i++)
{
temp= x[l[i]-1];
x[l[i]-1]=x[r[i]-1];
x[r[i]-1]=temp;
}
}
printf("%s",x);
return 0;
}
Any idea what is wrong or does it need to be optimized ?Is there better way to handle with case of many queries entered ?
scanf is a C function. string is a C++ data type. C++ can often use C datatypes, but it is very rare that C can use C++ datatypes. scanf was written about 20 years before C++ existed and has no clue what a string is.
Next, scanf takes a variable arguments list. It has no clue if the parameter types are correct and cannot easily check. It assumes that the programmer knows what they are doing.
End result, it tries to place char data as specified by the %s format option into a string. The string is written over with incompatible data and undefined behaviour occurs.
Replace the scanf with
cin >> x;
and go all C++. Alternative is to eschew C++ and go C style:
char x[appropriate size goes here];
scanf("%s",x);
Don't know the appropriate size? That's going to be a problem. string resizes to fit. The char array expected by scanf cannot. If you read more data than you can fit, Undefined Behaviour.
In
scanf("%d",num);
%d says the programmer passed in a pointer to an integer, in this case it would be the location of num so that scanf can update the value stored at num with whatever was read. The value of num was passed in. scanf assumes this is a pointer and Undefined Behaviour results. Most likely whatever uninitialized garbage value that is in num is used as a memory location and some unsuspecting block of memory gets overwritten. This will cause problems at some point in the future when you actually need the data that was at that memory.
scanf("%d",&num);
or in C++
cin >> num;
The remaining problems are variations on the preceding two problems.
scanf("%d,%d,%d",l[i],r[i],k[i]);
needs pointers
scanf("%d,%d,%d",&l[i],&r[i],&k[i]);
and
printf("%s",x);
wants a char array, not a string.
printf("%s",x.c_str());
gets the char array equivalent to the string.
Recommendation: Compile with a higher level of intolerance to errors that the compiler can survive. In g++ I use at least -pedantic -pedantic-errors -Wall -Wextra -Werror.
On a logical front, your input is all unchecked. A user could type in "rutabaga" for num with possibly comical results as your program tries to deal with non-numeric input. Again Undefined Behaviour. The program could crash. It could lock up. It could impregnate a male Llama.
In C++
if (cin >> num)
will catch some but not all forms of bad input. If this test fails, the contents of num are undefined and should not be used. Further, the stream will be in an error state and unreadable until the error is acknowledged and cleared. In C the equivalent is
if (scanf("%d",&num) == 1)
if scanf read exactly one value, num, all is good. Any other number of values read means scanf did not succeed and the contents of num are undefined.

Segmentation fault when calling virtual method

Here is my code, I casted the buffer to different type of objects, is this what causes the failure? I really want to know why the FromBase::find2(int key) works, but not FromBase::find(int key)?
class Base
{
public:
virtual int find(int key)=0;
int keys[4];
};
class FromBase:public Base
{
public:
FromBase();
int find(int key);
int find2(int key);
};
FromBase::FromBase()
{
for(int i=0;i<4;i++)
keys[i]=-1;
}
int FromBase::find(int key)
{
for(int i=0;i<4;i++){
if(keys[i]==key)
return i;
}
return i;
};
int FromBase::find2(int key)
{
for(int i=0;i<4;i++){
if(keys[i]==key)
return i;
}
return i;
};
int main()
{
FromBase frombase;
FILE* fptr=fopen("object.dat","w");
fwrite((void*)&frombase,48,1,fptr);
fclose(fptr);
char object[48];
fptr=fopen("object.dat","r");
fread((void*)object,48,1,fptr);
// looks like this works
(FromBase*)object->find2(7);
//These two do not work, I got segmentation fault!
(FromBase*)object->find(7);
(Base*)object->find(7);
}
The reason I want to do this is because I need to read the object from a file, thus I need to cast the buffer to an particular type then I can call the mothod.
There is a high chance that you are overwriting the virtual function table with your code leading to a bad address when you call the method. You cannot just save objects into a file and expect to restore them by just restoring the memory content at the time they were saved.
There are some nice libraries like boost::serialization to save and restore objects. I would urge you to read about this or to turn your objects into plain old data types (structs) containing no references or addresses.
There are several reasons why this code is not guaranteed to work. I think the biggest concern is this code here:
char object[48];
The number 48 here is a magic number and there's absolutely no guarantee that the size of the object you're writing out is 48 bytes. If you want to have a buffer large enough to hold an object, use sizeof to see how many bytes you need:
char object[sizeof(FromBase)];
Moreover, this is not guaranteed to work due to alignment issues. Every object in C++ has an alignment, some number that its address must be a multiple of. When you declare a variable, C++ ensures that it has the proper alignment for its type, though there's no guarantee that it ends up having the alignment of any other type. This means that when you declare a char array, there's no guarantee that it's aligned the same way as a real FromBase object would be, and using the buffer as an object of that type results in undefined behavior.
As others have pointed out, though, you also have a problem because this line:
fopen("object.dat","r");
Doesn't update the local variable you're using to keep track of the file pointer, so what you're reading back is almost certainly going to be garbage (if you read back anything at all). The segfault is probably coming from the bytes for the virtual dispatch table not being read back in correctly.
// will these two methods work? I got segmentation fault!
(FromBase*)object->find(7);
(Base*)object->find(7);
No they will not work. The segmentation fault might be a hint ;)
object is a type on the stack, which is fine, but you need to call the class constructor. If this was valid c++, ANY memory could be casted to any class.
I'd start off by creating the class on the stack and call some Load()-method on it, e.g.
FromBase object;
object.Load("object.dat");
And let the Load()-method read the data from file and set values on the internal data.
Apart from all the other problems that people have pointed out.
I absolutely shocked that nobody has mentioned that:
(FromBase*)object->find2(7);
Is just NOT guaranteed to work.
You are depending on a raft of implementation details. object is an array of char! Not a FromBase thus the compiler has not had the chance to initialize any of its implementation dependent details.
Even if we assume that the implementation uses a vtable (and thus a vtable pointer in the class). Does the implementation use a relative pointer or an absolute pointer. Assuming you want to save with one run and then reload the next time? Are you assuming the vtable is actually located in the same location between different runs (what happens when you load this part of the application from a dynamic library)!
This is just horrible. You SHOULD NOT DO THIS EVER.
If you want to serialize and de-serialize the object from storage. Then the class has to know how to do the serialization itself. Thus all the correct constructors/destructors get called at the correct time.
First problem I can see when you use fopen second time:
fopen("object.dat","r"); //problem - your code
which should be this:
fptr = fopen("object.dat","r"); //fix (atleast one fix)
That means, in your code you're trying to read data using fptr which is already closed!
One problem is that the array of characters do not have a method called find.
The cast do not convert the array to FromBase or Base. It only tells the compiler to ignore the error.