string.substr call leads to hung program

Hello!

I have a code which takes an original string and and then breaks that string into chunks based on the presence of specific characters (I am taking a string equation and computing it). In order to break the mother string into smaller chunks I make use of string.substr(a,b), where a and b are variables determined elsewhere.

When I compile and run my program (I am using Dev-c++ v.4.9.9.2) the program hangs on a call to string.substr(a,b). When I recompile and run in debug mode, everything works like a charm - I'm stumped!

Here's the function with the hang up
1
2
3
4
5
6
7
  int decoStr( string str , int a , int b   ){
    int c = b-a;
    string str1;
    str1 = str.substr(a,c); // <-- this is where the hang happens
    int n = atoi(str1.c_str());
    return(n);    
}


Thanks for your help all! And if you need more of the program or more information, please ask!!!
What is the contents of str, and what are the values of a and b when the problem occurs?
If you don't know the answer, then try putting a cout statement at the start of the function in order to show the values.

Incidentally, Dev-c++ v.4.9.9.2 was last updated around 2005 and is obsolete. The current up to date version is Version 5.5.1 - 7 October 2013
http://orwelldevcpp.blogspot.co.uk/
oh geez! i will update that asap, thank you!

str = "101+34+2-3";
a = 0;
b = 8;

and then I get and 'send error report' pop-up and the terminal hangs for a few seconds before closing
I don't see a problem with those specific values of a, b and str.
It gives str1: 101+34+2
and x: 101

When I deliberately pass invalid values of a and b, I get this:
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

I don't see anything specifically wrong with that code and with the specified input. Are you sure that is where the problem occurs?
thank you Chervil for your help

I am fairly certain this is where the program hangs as I put cout statements on the line before and after the str.substr(a,b).

Also the error you get isnt what I get - I just get a hang - as if there were an infinite loop in the str.substr(a,b) call.
Well, it seems as if you have this reasonably well tied down with the cout statements.

I did have a doubt because recently there was a question about an error with substr() but it turned out it there was more than one use of substr in that code, and the problem was on one of the other lines.

Could you post the entire program please?
sure thing! its pretty ugly...

if you have suggestions on anything else in the program please dont hesitate to comment!

I should also note that I updated, and the program doesn't compile because I get errors around the function atoi (which I didnt get in 4.xxx) - this may have something to do with my problem.

i will get back as soon as i resolve this new issue

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
#include <iostream>
#include <fstream>
#include <string>
#include<math.h>
using namespace std;

/*
Program to calculate user supplied equations involving simple arithmetic
*/

// Declare global variables
string Equation;
//
// Function to count and locate given character in given string 
class collectChar{
    public:
    int cN;
    int *sstr;
    int sstrN;
    char iChar;
    string iStr;
    int *spot;
    collectChar(char,string);
//    cout << ii << endl;
    int charNum( char , string ) ;
    int charLoc( char , string , int );
    int deconEq( char , string , int );
};
// collectChar constructor
collectChar::collectChar(char a,string b){
    iChar = a;
    iStr = b;  
    charNum(a,b);
    charLoc(a,b,cN);
    sstr = new int[2*cN];
    cout<<"decoeq"<< endl;
    deconEq(a,b,cN);
    cout<<" made it"<<endl;
}
// function to count occurances of given string iChar in given string iStr
int collectChar::charNum(char iChar,string iStr) {
    int n = 0;
    int nn = 0;
    while( iStr.find(iChar,n) < iStr.length() ){
        n = iStr.find(iChar,n);
        n = n+1;
        nn = nn + 1;
    }
    cN =  nn;
    return(nn);
} 
// function to give address of given string iChar in given string iStr
int collectChar::charLoc(char iChar , string iStr , int N ) {
    int n = 0;
    int nn = 0;
    spot = new int[N];
    while( iStr.find(iChar,n) < iStr.length() ){
        n = iStr.find(iChar,n);
        spot[nn] = n;
        n = n+1;
        nn = nn + 1;
    }
    return(nn);
} 
// Function to get user equation
void getEq(){
    /*
    cout << "Please enter equation using only addition and subtraction"<<endl;
    cout << "(e.g. 1+2, 1+2-3+14-25, etc)"<<endl;
    cin >> Equation;
    cin.get();
    */
    Equation = "101+34+2-3";
}
// Function to deconstruct user eq string with numbers and operators
int collectChar::deconEq( char operI , string eqI , int n){
    int i;
    cout << operI<<" "<<eqI<<" "<<n<<"  "<<cN<<endl; 
    if (cN!=0){     
        sstr[0] = 0;
        sstr[1] = spot[0];
        for (i=1;i<cN;i++){
            sstr[2*i  ] = sstr[2*i-1] + 1;
            sstr[2*i+1] = spot[i  ];
        }
        sstr[2*i  ] = sstr[2*i-1] + 1;
        sstr[2*i+1] = eqI.length() ;
        sstrN = 2*i+1;
    } else {
        sstr[0] = 0;
        sstr[1] = eqI.length();
    }
    cin.get();
    return(cN);
}
// Function to verify user input with y or n
void usrVer(){
    string usrRe;
    cout << "(y for yes, n for no)"<<endl;
    cin >> usrRe;
    cin.get();
    if ( usrRe == "y" ) 
        cout << "Good";
    else if ( usrRe == "n" )
        cout << "Bad";
    else 
        cout << "Ugly";
}
int decoStr( string str , int a , int b   ){
    int c = b-a;
    cout <<str<<" ? "<<a<<" "<<c<<endl;
    cout << str.substr(a,c)<<"++"<<endl;
    string str1;
    str1 = str.substr(a,c);
    cout << "!"<<str1<<endl;
    int n = atoi(str1.c_str());
    return(n);    
}
int main(){
    string strx, stry, stru, strv, strp;
    int a, b, m, mx, my, mm, mx1, i;
    m = 0;
    my = 0;
    mx = 0;
    cout << "m begins: " << m << endl;
    getEq();
    strv = Equation;
    cout << "f"<<endl;
    collectChar yy('-',strv);
    cout << "a" << yy.cN<<endl;
    if (yy.cN!=0){ // there is subtraction
        cout<<strv<<" ";
        cout<<yy.sstr[0]<<yy.sstr[1]<<endl;
        a = yy.sstr[0];
        b = yy.sstr[1] - a;
        stry = strv.substr(a,b);
        cout<<stry<<endl;
        collectChar xx('+',stry);
        cout << "b "<<xx.cN << endl;
        if (xx.cN!=0){ // there is addition
            mx += decoStr(stry,xx.sstr[0],xx.sstr[1]);
            i = 2;
            while (i<xx.sstrN){
                mm = decoStr(stry,xx.sstr[i],xx.sstr[i+1]);
                mx += mm;
                i += 2;
            }
            cout << "mx  "<<mx<<endl;
        } else { // no addition
            mx1 = atoi(stry.c_str());
            mx += mx1;
        }
        my += mx;
        mx = 0;
        i = 2;
        while (i<yy.sstrN){
            cout << strv << endl;
            cout << "0123456789012345678901234567890"<<endl;
            cout<<i<<" "<<yy.sstr[i]<<" "<<yy.sstr[i+1]<<endl;
            stry = strv.substr(yy.sstr[i],yy.sstr[i+1]);
            collectChar xx('+',stry);
            cout << " mlo: xx.cN "<<xx.cN<<endl;
            if (xx.cN!=0){ // there is addition
                mx1 = decoStr(stry,xx.sstr[0],xx.sstr[1]);
                mx -= mx1;
                cout << mx<<" ";
                i = 2;
                while (i<xx.sstrN){
                    mm = decoStr(stry,xx.sstr[i],xx.sstr[i+1]);
                    mx += mm;
                    i += 2;
                    cout << mx <<" ";
                }
            } else { // no addition
                mx1 = atoi(stry.c_str());
                mx -= mx1;
                cout << mx << " ";
            }
            my += mx;
            cout <<mx<<endl;
            mx = 0;
            i += 2;
        }
    } else { // no subtraction
        collectChar xx('+',strv);
        if (xx.cN!=0){
            mx += decoStr(strv,xx.sstr[0],xx.sstr[1]);
            i = 2;
            while (i<xx.sstrN){
                mm = decoStr(strv,xx.sstr[i],xx.sstr[i+1]);
                mx += mm;
                i += 2;
            }
        } else {
            mx1 = atoi(strv.c_str());
            mx += mx1;
        }
        my += mx;
    }
    m += my ;    
//    cout << "Alright, you want me to calculate "<<Equation<<"?"<<endl;
//    usrVer();
    
    
    
    cout<<m<<endl;
    cin.get();
    return 0;
while (iStr.find(iChar, n) < iStr.length()){
should be
while (iStr.find(iChar, n) != std::string::npos){
although, the semantics should be equivalent in practice.

In deconEq, you write to memory out of the bounds of sstr. Check your logic there.
thank you cire!

for deconEq I was trying (and failing) to dynamically allocate memory to sstr. Is it possible to allocate memory as I am getting values for sstr?

finally caught my mistake! thanks cire!
Last edited on
So after I updated dev-c++ i got errors for atoi since i didn't include stdlib.h. Now that I have updated and include stdlib.h everythings hunky-dory!

Thanks Chervil and cire!
Glad you got it updated.

One point, in C++ the proper include should be <cstdlib> and <cmath> rather than <stdlib.h> and <math.h>

Topic archived. No new replies allowed.