"Segmentation fault (core dumped)" While Using Recursion

Please Note: This is a homework assignment, however, the due date has already passed and I'm just doing it for the learning aspect. If you've seen my previous posts, yes, I'm really good at turning in my homework on time... :P

Anyways, the goal of the homework assignment is to take a partly completed assignment (which can be found here: https://drive.google.com/file/d/15CnL4ViqaLx7eOAgrkQMOUxYkojTz2xp/view) and fix the FIXME's stated in the code.

I've fixed most of it, but the final FIXME I'm stuck on.

The part I'm having trouble with is I'm supposed to start with an octal number and convert it to a decimal number & return that decimal number.

The problem is I get a "segmentation fault (core dumped)" for the recursion part but I'm not sure how to fix it.

Current Output:
1
2
3
4
5
6
7
8
9
Program converts decimal number into binary
 and octal number systems and vice versa.

Enter a number in decimal: 564

(564) base 10 = (1000110100) base 2
(1000110100) base 2 = (564) base 10
Decimal to Octal Representation = 1064
Segmentation fault (core dumped)


Full Code:
(Note: Recursion line causing the problem is on line 198.)
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
/*
    Exception and Recursion

	Updated by: Piggy - #FIXED#
	Date: 4/3/2019 - 4/10/2019 - #FIXED#

	Program Info: Number system converter  

	The program uses recursion to find the binary, and octal representation of
	given decimal number and vice versa.
*/
#include <iostream> 
#include <cstdio>
#include <string>
#include <cmath>
using namespace std;
using llu = unsigned long long int;

// System specific macro function sysclear that 
// clears console text
#ifdef _WIN32
#define sysclear() system ("cls") // not secure!
#else
#define sysclear() system ("clear") // not secure!
#endif

// Recursively converts decimal number to binary representation
string decToBin(llu num);

// Recursively converts binary number to decimal representation
llu binToDec(string binaryNum, int weight);

// Recursively converts decimal number to octal representation
string decToOct(llu num);

// Recursively converts octal number to decimal representation
llu octToDec(string octNum, int weight);

int main()
{
	llu decimalNum;
	int numPosition;
	int binaryNum;

	numPosition = 0;
	bool valid = false;

	string response = "yes";
	while (response == "yes")
	{
		sysclear();
		valid = false;
		cout << "Program converts decimal number into binary \n and octal number systems and vice versa.\n\n";
		// User input with validation
		do
		{
			cout << "Enter a number in decimal: ";
			try
			{
				cin >> decimalNum;
				if (cin.fail())
				{
					throw "Invalid input. Try again!";
				}
				valid = true;
			}
			catch (const char *error)
			{
				cin.clear(); // clear the cin failure state
				cin.ignore(100, '\n'); // ignore next 100 characters or up to \n char
				printf("%s\n", error);
			}
		} while (!valid);

		cout << endl;

		string binary = decToBin(decimalNum);

		printf("(%llu) base 10 = (%s) base 2\n", decimalNum, binary.c_str());
		printf("(%s) base 2 = (%llu) base 10\n", binary.c_str(), binToDec(binary, numPosition));

		// FIXME1 - call decToOct function passing proper argument and - 
		// display the values with proper descriptions. (10 points - FIXED)
		cout << "Decimal to Octal Representation = " << decToOct(decimalNum) << '\n';
		// FIXME2 - call octToDec function passing proper argument and 
		// display the values with proper descriptions. (10 points - FIXED)
		cout << "Octal to Decimal Representation = " << octToDec(binary, numPosition) << '\n';

		cin.ignore();
		cout << "Would you like to convert another number? Enter yes/no:\n";
		cin >> response;
	}
	cin.ignore();
	cout << "Good bye! Enter to quit!";
	cin.get();
	return 0;
}

string decToBin(llu num) {
    /*
		Algorithm steps:
		1. base case: binary of decimal num less than 2 is that number itself
		2. Otherwise,
			a. Concatenate all the remainders in reverse order and return it
	*/
    if (num < 2) {
        return to_string(num);
    }
    else
        return decToBin(num/2) + to_string(num%2);
}


llu binToDec(string binaryNumber, int position)
{
	/*
	binary number is received as a string value
	Algorithm steps:
	1. base case: if binaryNumber is empty or 0, decimal is 0
	2. otherwise, 
		i. extract the rightmost bit
		ii. convert char bit into int , e.g., '1' is converted to 1
		iii. get the decimal value for the bit position by using formula bit*pow(2, position)
		iv. recursively find the decimal value of the rest of the bits and add all the returned 
			values
	3. return the final decimal value
	*/
	char bit;
	llu dec = 0;

	if (binaryNumber.length() == 0) // base case
		return 0;
	else
	{
		unsigned int index = binaryNumber.length() - 1;
		bit = binaryNumber[index]; // 2.i
		bit = int(bit) - int('0'); // 2.ii
		llu bitValue = bit * static_cast<int>(pow(2.0, position)); // 2.iii
		dec = bitValue;
		binaryNumber = binaryNumber.substr(0, binaryNumber.length() - 1); //remove the last bit
		position++; // increment the position
		dec += binToDec(binaryNumber, position); // 2.iv
		return dec; // 3
	}
}

// FIXME3 - implement decToOct function (40 points - FIXED)
string decToOct(llu num)
{
	/*
	Algorithm steps:
	1. base case: if octal of decimal num < 8 is that number itself
	2. Otherwise,
        a. Concatenate all the remainders in reverse order and return it
	*/
	if (num < 8)
		return to_string(num);
	else
		return decToOct(num / 8) + to_string(num % 8);
}

// FIXME4 - implement octToDec function (40 points - Work in progress. Having an issue with, but should be working??)
llu octToDec(string octalNumber, int position) {
	/*
	Octal number is received as a string value and
	the first position from the back
	
	Algorithm steps:
	1. base case: if octalNumber is empty or 0, decimal is 0
	2. otherwise,
		i. extract the rightmost number
		ii. convert char value into int , e.g., '7' is converted to 7
		iii. get the decimal value for the octal position using formula
             octal*pow(8, position)
		iv. recursively find the decimal value of the rest of the octal
            numbers and add all the returned values
	3. return the final decimal value
	*/
	char octal;
    llu octalNum;
    llu decTotal = 0;

	// base case
	if (octalNumber.length() == 0) {
		return 0; // Step 1 of algorithm steps
	}

	// general case
	else {
		// Extracts the rightmost number.
		unsigned int index = octalNumber.length() -1;
		octal = octalNumber[index]; // 2.i
		octalNum = int(octal) - int('0'); // 2.ii
        decTotal = octalNum % 8;
        octalNum = octalNum / 8;
        position++;
        // Issue is with the recursion:
        octToDec(to_string(octalNum), position);
        
        return decTotal; // step 3
	}
}


Help would be greatly appreciated, thank you!


Edit: Part of my code is based off this StackOverFlow post that has to do with Recursion:
https://stackoverflow.com/questions/36000311/any-idea-how-to-convert-and-octal-number-to-a-decimal-with-recursion

But for some reason it's not working for me. My guess is something related to the position variable because the stack overflow post did not have that.
Last edited on
run through a debugger and watch the backtrace, you'll notice infinite recursion
1
2
#40 0x000055555555c4b0 in octToDec (octalNumber="0", position=65453) at foo.cpp:195
#41 0x000055555555c4b0 in octToDec (octalNumber="0", position=65452) at foo.cpp:195 

the problem is that you never reach the base case.
The problem of line 198 is that to_string(...) will not return an empty string. It will be at least "0" hence line 184 will never become true.
FWIW the octal part is seriously overengineered (its well done, but its the hard way).
one octal digit is a nibble. take them in pairs, and its bytes. push the bytes into an integer directly and print the integer and its done. That is the simple DIY method. C++ can directly convert for you as well, but that seems out of scope for the exercise.


Thank you for your replies!

ne555 wrote:
run through a debugger and watch the backtrace, you'll notice infinite recursion...

I suspected it had to do with the recursion, but as I'm new to recursion I couldn't tell what specifically is wrong with it that is causing it to never reach the base case.

coder777 wrote:
The problem of line 198 is that to_string(...) will not return an empty string. It will be at least "0" hence line 184 will never become true.

Ahh okay. I've fixed it accordingly. I've also improved the code a bit. But it's still not working. I'll provide code at bottom of this entire message.

jonnin wrote:
FWIW the octal part is seriously overengineered (its well done, but its the hard way).
one octal digit is a nibble. take them in pairs, and its bytes. push the bytes into an integer directly and print the integer and its done. That is the simple DIY method. C++ can directly convert for you as well, but that seems out of scope for the exercise.

Sorry, I don't fully understand what you mean. Is this close to what you meant?

Current Code:
Notes:
- Doesn't work still.
- Sorry if the format looks a bit off. I think it looks fine in this link:
http://cpp.sh/6ygqz
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
/*
	Updated by: Piggy - #FIXED#
	Date: 4/3/2019 - 4/11/2019 - #FIXED#

	Program Info: Number system converter  

	The program uses recursion to find the binary, and octal representation of
	given decimal number and vice versa.
*/
#include <iostream> 
#include <cstdio>
#include <string>
#include <cmath>
using namespace std;
using llu = unsigned long long int;

// System specific macro function sysclear that 
// clears console text
#ifdef _WIN32
#define sysclear() system ("cls") // not secure!
#else
#define sysclear() system ("clear") // not secure!
#endif

// Uncomment to show debug messages:
//#define DEBUG

// Recursively converts decimal number to binary representation
string decToBin(llu num);

// Recursively converts binary number to decimal representation
llu binToDec(string binaryNum, int weight);

// Recursively converts decimal number to octal representation
string decToOct(llu num);

// Recursively converts octal number to decimal representation
llu octToDec(string octNum, int weight);

int main()
{
	llu decimalNum;
	int numPosition;
	//int binaryNum;

	numPosition = 0;
	bool valid = false;

	string response = "yes";
	while (response == "yes")
	{
		sysclear();
		valid = false;
		cout << "Program converts decimal number into binary \n and octal number systems and vice versa.\n\n";
		// User input with validation
		do
		{
			cout << "Enter a number in decimal: ";
			try
			{
				cin >> decimalNum;
				if (cin.fail())
				{
					throw "Invalid input. Try again!";
				}
				valid = true;
			}
			catch (const char *error)
			{
				cin.clear(); // clear the cin failure state
				cin.ignore(100, '\n'); // ignore next 100 characters or up to \n char
				printf("%s\n", error);
			}
		} while (!valid);

		cout << endl;

		string binary = decToBin(decimalNum);

		printf("(%llu) base 10 = (%s) base 2\n", decimalNum, binary.c_str());
		printf("(%s) base 2 = (%llu) base 10\n", binary.c_str(), binToDec(binary, numPosition));

		// FIXME1 - call decToOct function passing proper argument and - 
		// display the values with proper descriptions. (10 points - FIXED)
		cout << "Decimal to Octal Representation = " << decToOct(decimalNum) << '\n';
		// FIXME2 - call octToDec function passing proper argument and 
		// display the values with proper descriptions. (10 points - FIXED)
		cout << "Octal to Decimal Representation = " << octToDec(binary, numPosition) << '\n';

		cin.ignore();
		cout << "Would you like to convert another number? Enter yes/no:\n";
		cin >> response;
	}
	cin.ignore();
	cout << "Good bye! Enter to quit!";
	cin.get();
	return 0;
}

string decToBin(llu num) {
    /*
		Algorithm steps:
		1. base case: binary of decimal num less than 2 is that number itself
		2. Otherwise,
			a. Concatenate all the remainders in reverse order and return it
	*/
    if (num < 2) {
        return to_string(num);
    }
    else
        return decToBin(num/2) + to_string(num%2);
}


llu binToDec(string binaryNumber, int position)
{
	/*
	binary number is received as a string value
	Algorithm steps:
	1. base case: if binaryNumber is empty or 0, decimal is 0
	2. otherwise, 
		i. extract the rightmost bit
		ii. convert char bit into int , e.g., '1' is converted to 1
		iii. get the decimal value for the bit position by using formula bit*pow(2, position)
		iv. recursively find the decimal value of the rest of the bits and add all the returned 
			values
	3. return the final decimal value
	*/
	char bit;
	llu dec = 0;

	if (binaryNumber.length() == 0) // base case
		return 0;
	else
	{
		unsigned int index = binaryNumber.length() - 1;
		bit = binaryNumber[index]; // 2.i
		bit = int(bit) - int('0'); // 2.ii
		llu bitValue = bit * static_cast<int>(pow(2.0, position)); // 2.iii
		dec = bitValue;
		binaryNumber = binaryNumber.substr(0, binaryNumber.length() - 1); //remove the last bit
		position++; // increment the position
		dec += binToDec(binaryNumber, position); // 2.iv
		return dec; // 3
	}
}

// FIXME3 - implement decToOct function (40 points - FIXED)
string decToOct(llu num)
{
	/*
	Algorithm steps:
	1. base case: if octal of decimal num < 8 is that number itself
	2. Otherwise,
        a. Concatenate all the remainders in reverse order and return it
	*/
	if (num < 8)
		return to_string(num);
	else
		return decToOct(num / 8) + to_string(num % 8);
}

// FIXME4 - implement octToDec function (40 points - Work in Progress. Not working)
llu octToDec(string octalNumber, int position) {
	/*
	Octal number is received as a string value and
	the first position from the back
	
	Algorithm steps:
	1. base case: if octalNumber is empty or 0, decimal is 0
	2. otherwise,
		i. extract the rightmost number
		ii. convert char value into int , e.g., '7' is converted to 7
		iii. get the decimal value for the octal position using formula
             octal*pow(8, position)
		iv. recursively find the decimal value of the rest of the octal
            numbers and add all the returned values
	3. return the final decimal value
	*/

	int octal;
    llu octalNum = 0;
    llu decTotal = 0;

	/*
	=================================================
	Should be able to input 1064 (oct) and get out
	564 (dec) to know it works properly.
	
	STATUS: Doesn't work.
	=================================================
	*/
    #ifdef DEBUG
    cout << "\nDEBUG1 octalNumber = " << octalNumber << '\n';
	cout << "DEBUG1 octalNum = " << octalNum << '\n';
    cout << "DEBUG1 decTotal = " << decTotal << "\n\n";
    #endif
    
	// base case
	if (octalNumber == "0") {
		return 0; // Step 1 of algorithm steps
	}

	// general case
	else {
		// Extracts the rightmost number.
		octalNumber.pop_back(); // 2.i
		octalNum = stoi(octalNumber); // 2.ii
		#ifdef DEBUG
		cout << "[DEBUG] octalNum after stoi(octalNumber): " << octalNum << '\n';
		#endif
        decTotal = octalNum % 8;
        octalNum = octalNum / 8;
        #ifdef DEBUG
        cout << "[Debug] decTotal after math calcs: " << decTotal << '\n';
        #endif
		position++;
		
		// Issue is with the recursion?
		//octToDec(to_string(octalNum), position);
        decTotal += octToDec(to_string(octalNum), position);
        
        #ifdef DEBUG
        cout << "DEBUG# octalNum = " << octalNum << '\n';
		cout << "DEBUG# decTotal = " << decTotal << "\n\n";
        #endif
        
        return decTotal; // step 3
	}
}
Last edited on
Nevermind :) I havent worked in octal in a while, and messed that up.
jonnin wrote:
Nevermind :) I havent worked in octal in a while, and messed that up.

Ah okay, no worries!
Topic archived. No new replies allowed.