Error code 139 - Segmentation Fault

I run in code block or visual studio, it worked fine. However, when I test in cpp.sh it's occur the error: Error code 139 - Segmentation Fault. Please, help, thx for your time.
Here is all my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  #include <iostream>
#include <string>
#include <stdlib.h>
#include <sstream>

using namespace std;

bool isOperator(char ch)
{
    return (ch == '+') ||
           (ch == '-') ||
           (ch == '*') ||
           (ch == '/');
}
bool isHigherPrior(char ch)
{
    return (ch == '/') ||
           (ch == '*');
}
bool isOperand(char ch)
{
    return ('0' < ch && ch < '9');
}
bool isLeftParen(char ch)
{
    return (ch == '(');
}
bool isRightParen(char ch)
{
    return (ch == ')');
}
string arrange(string str)
{
    for(unsigned int i=0; i<str.size(); i++)
    {
        if(str[i] == ' ')                           // delete space
        {
            str.erase(i, 1);
            i--;
        }
        if(str[i] == '+' && isOperator(str[i-1]))   // delete unary plus
        {
            str.erase(i, 1);
            i--;
        }
    }
    for(unsigned int i=0; i<str.size(); i++)
    {
        if((isLeftParen(str[i]) && isRightParen(str[i+1])) || (isRightParen(str[i]) && isLeftParen(str[i+1]))) // delete case () and )(
        {
            str.erase(i, 2);
            i=i-2;
        }
        if(isOperator(str[i]) && isOperator(str[i+1]))
        {
            if(str[i]=='-' && str[i+1]=='-')        // -- = +
            {
                str.erase(i, 2);
                str.insert(i, "+");
                i--;
            }
            else if(str[i]=='+' && str[i+1]=='-')   // +- = -
            {
                str.erase(i, 2);
                str.insert(i, "-");
                i--;
            }
        }
    }
    return str;
}
bool checkValidity(string str, int &paren)
{
    bool valid = true;
    int left=0, right=0;
    arrange(str);
    if(isOperator(str[str.size()-1]) || isHigherPrior(str[0]))          // *, / at the first string or any operator at last => error
        valid = false;
    for(unsigned int i=0; i<str.size(); i++)
    {
        if(isLeftParen(str[i]))                                         // count left parenthesis
        {
            if(isOperand(str[i-1]) || isRightParen(str[i+1]))           // number( or () => error
            {
                valid = false;
                break;
            }
            left++;
        }
        if(isRightParen(str[i]))                                        // count right parenthesis
        {
            if(isOperand(str[i+1]))                                     // )number => error
            {
                valid = false;
                break;
            }
            right++;
        }
        if(isOperator(str[i]) && isHigherPrior(str[i+1]))               // +/ or -* ... => error
        {
            valid = false;
            break;
        }
        if(!isOperand(str[i]) && !isOperator(str[i]) && !isLeftParen(str[i]) && !isRightParen(str[i]) && str[i]!='.') // letter => error
        {
            valid = false;
            break;
        }
    }
    if(left != right){              // left parenthesis != right => error
        valid = false;
    }
    if(valid == false)              // invalid
    {
        cout << "Expression is invalid" << endl;
        return false;
    }
    else                            // valid, number of parenthesis = left parenthesis
    {
        paren = left;
        return true;
    }
}
double eval(string str, int num)
{
    int posL, posR;
    while(num>0)                // recursive to evaluate in (...);
    {
        posR = str.find(")");
        posL = str.rfind("(", posR);
        string temp = str.substr(posL+1, posR-posL-1);
        double t = eval(temp, 0);
        stringstream ss;
        ss << t;
        str.replace(posL, posR-posL+1, ss.str());
        str = arrange(str);
        num--;
    }
    double left, right;
    unsigned int j;
    for(j=0; j<str.size(); j++)
    {
        if(isHigherPrior(str[j]))               // evaluate * / first and + -
        {
            unsigned int l;
            for(l=j-1; l>=0; l--)                       // take left operator
                if(isOperator(str[l]))
                    break;
            if(l == 0)                            // unary minus e.g: (-3)
            {
                left = atof(str.substr(l, j-l).c_str());
                str.erase(l, 1);
                l--;
                j--;
            }
            else
                left = atof(str.substr(l+1, j-l-1).c_str());
            if(str[l] == '-' && isOperator(str[l-1]))              // unary minus
            {
                left = -1*left;
                str.erase(l-1, 1);
                l--;
                j--;
            }
            unsigned int k;
            for(k=j+1; k<str.size(); k++)                       // take right operator
                if(isOperator(str[k]))
                    break;
            if(isOperator(str[j+1]))                            // unary minus
            {
                str.erase(j+1, 1);
                for(k=j+1; k<str.size(); k++)
                    if(isOperator(str[k]))
                        break;
                right = -1*atof(str.substr(j+1, k-j-1).c_str());
            }
            else
                right = atof(str.substr(j+1, k-j-1).c_str());
            switch(str[j])
            {
                case '*':
                {
                    double t = left * right;
                    stringstream ss;
                    ss << t;
                    str.replace(l+1, k-l-1, ss.str());
                    break;
                }
                case '/':
                {
                    double t = left / right;
                    stringstream ss;
                    ss << t;
                    str.replace(l+1, k-l-1, ss.str());
                    break;
                }
            }
            j=-1;
        }
    }
    str = arrange(str);
    for(unsigned int i=0; i<str.size(); i++)                      // + -
    {
        if(isOperand(str[i]))
        {
            unsigned int l;                      // take left operator
            for(l=i; l<str.size(); l++)
                if(isOperator(str[l]))
                    break;
            if(l==str.size())
                break;
            left = atof(str.substr(i, l-i).c_str());
            if(str[i-1] == '-')
            {
                left = -1*left;
                str.erase(i-1, 1);
                i--;
                l--;
            }
            unsigned int k;                      // take right operator
            for(k=l+1; k<str.size(); k++)
                if(isOperator(str[k]))
                    break;
            right = atof(str.substr(l+1, k-l-1).c_str());
            switch(str[l])
            {
                case '+':
                {
                    double t = left + right;
                    stringstream ss;
                    ss << t;
                    str.replace(i, k-i, ss.str());
                    break;
                }
                case '-':
                {
                    double t = left - right;
                    stringstream ss;
                    ss << t;
                    str.replace(i, k-i, ss.str());
                    break;
                }
            }
            i=-1;
        }
    }
    double t = atof(str.c_str());
    str = "";
    return t;
}
int main()
{
    // (3-  - 2) + (4 -3 ) - - 4 = 10
    // 3 +2 -- ++ ( 2.4 - 4.4 ) -4  * 3 = -9
    // ((((3-4*2)* 2.2 + 3* (-4.4-2))-2.1)/-2)-1() = 15.15
    // 3(3+2) : *error
    // (2-3)3 : *error
    // ** or // or +* ... : *error
    string str;
    int paren = 0;
    cout << "Input an infix arithmetic expression:" << endl;
    getline(cin, str);
    str = arrange(str);
    if(checkValidity(str, paren))
        cout << "The result is: " << eval(str, paren) << endl;
    return 0;
}
So what do you type in to make it crash?

Only 3+2 to test
also, any expression on the comments in main function work properly
Check your array subscripts.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ g++ -g -std=c++11 foo.cpp
$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) run
Starting program: /home/sc/Documents/a.out 
Input an infix arithmetic expression:
3+2

Program received signal SIGSEGV, Segmentation fault.
0x00000000004025ee in eval (str="3+2", num=0) at foo.cpp:213
213	            if(str[i-1] == '-')
(gdb) bt
#0  0x00000000004025ee in eval (str="3+2", num=0) at foo.cpp:213
#1  0x0000000000402bf6 in main () at foo.cpp:265
(gdb) list 213
208	                if(isOperator(str[l]))
209	                    break;
210	            if(l==str.size())
211	                break;
212	            left = atof(str.substr(i, l-i).c_str());
213	            if(str[i-1] == '-')
214	            {
215	                left = -1*left;
216	                str.erase(i-1, 1);
217	                i--;
(gdb) print i
$1 = 0

You're trying to access str[-1]
thx, now I notice it.
Topic archived. No new replies allowed.