My concern in this question is not where the bug is but rather why the compiler responds to this bug this particular way. The bug is in case k==4 in the first loop. The value of "current" can be -1 sometimes which causes the issue.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct com
{
int type,k,ver;
string s,res;
bool b;
com()
{
k=type=ver=-1;
s="";
b=false;
res="";
}
};
int main() {
int Q,k;
string W;
cin>>Q;
int current=0;
vector<com> com_his;
for(int i=0;i<Q;i++) //<--FIRST LOOP
{
cin>>k;
if(k==1)
{
cin>>W;
com t;
t.type=1;
t.s=W;
// if(com_his)
t.ver=i;
current=i;
com_his.push_back(t);
}
else if(k==2)
{
cin>>k;
com t;
t.type=2;
t.k=k;
t.ver=i;
current=i;
com_his.push_back(t);
}
else if(k==3)
{
cin>>k;
com t;
t.type=3;
t.k=k;
t.ver=current;
// while()
com_his[current].b=true;
com_his.push_back(t);
}
else if(k==4)
{
// cin>>W;
com t;
t.type=4;
// t.s=W;
current--;
while(com_his[current].type==3||com_his[current].type==4)
current--;
t.ver=current;
com_his[current].b=true;//<--THIS IS THE BUG. SOMETIMES "current" can be -1 which causes the issue.
com_his.push_back(t);
}
}
string s="";
cout<<"SIZE IS "<<com_his.size()<<endl;
for(int i=0;i<Q;i++) //<--SECOND LOOP
{
k=com_his[i].type;
cout<<i<<" "<<Q<<endl;
cout<<"HOWDY"<<endl;
}
// cout<<"HALLO\n";
return 0;
}
However my concern is why doesn't the compiler say segmentation fault when this happens? For example if I provide this input
10
1 lchbfcjtfpsmjrqsdgci
3 19
1 cpcvixlm
1 apdjgjydvpbpvyiy
2 29
4
4
3 9
4
4
I get this output in all the different compilers I have tried:
SIZE IS 10
0 10
HOWDY
1 10
HOWDY
2 10
HOWDY
3 10
HOWDY
4 10
HOWDY
5 10
HOWDY
6 10
HOWDY
7 10
HOWDY
8 10
HOWDY
9 10
HOWDY
And then I get an error. In different compilers I get different errors. While using Hakerrank I got this error:
double free or corruption (!prev)
Reading symbols from Solution...done.
[New LWP 73923]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./Solution'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
To enable execution of this file add
add-auto-load-safe-path /usr/local/lib64/libstdc++.so.6.0.25-gdb.py
line to your configuration file "//.gdbinit".
To completely disable this security protection add
set auto-load safe-path /
line to your configuration file "//.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual. E.g., run from the shell:
info "(gdb)Auto-loading safe path"
While using Dev C++ 5.11 in windows I get this:
Process exited after 8.516 seconds with return value 3221226356
While using c++ 14 on online gdb at https://www.onlinegdb.com/ I get this:
Compiled Successfully. memory: 2792 time: 0.17 exit code: 134
My question is if out of memory accessed occurred in first loop why does the second loop even execute at all? The output of all 3 compilers is same despite their errors being different. So how does the code even reach the second loop? I'm just trying to understand this behavior.
For MORE INFO: I was trying to solve this problem: https://www.hackerrank.com/challenges/simple-text-editor/problem In this challenge, you must implement a simple text editor. Initially, your editor contains an empty string, S. You must perform Q operations of the following types:
1)append(W):Append string W to the end of S.
2)delete(k):Delete the last k characters of S.
3)print(k):Print the kth character of S.
4)undo:Undo the last (not previously undone) operation of type 1 or 2 , reverting S to the state it was in prior to that operation.
Input Format
The first line contains an integer, Q, denoting the number of operations. Each line i of Q the subsequent lines (where 0<=i<Q) defines an operation to be performed. Each operation starts with a single integer, t (where t={1,2,3,4}), denoting a type of operation as defined in the Problem Statement above. If the operation requires an argument, is followed by its space-separated argument t. For example, if t=1 and W="abcd" , line i will be 1 abcd.