Hello. I'm writing a runaround number program for an assignment.
Part of my code is below and there's a line where segmentation fault occurred, and I can't figure out why.
And I think other parts of the code after this segment encountered the same problem too, but the error should be similar to this, hence I didn't include the whole code.
Appreciate if someone can guide me to the right direction. Thanks!
RunAroundChecker::RunAroundChecker( int number )
//Pre: Takes in a positive number
//Post: The number is split into digits and stored internally
// In this case, as a linkedlist.
// The check of RunAround property should also be performed.
{
_head = NULL;
_size = 0;
_runAround = true;
_isValid = true;
//Split the digits and store in a linked list
while (number != 0) {
int newDigit = number % 10;
number /= 10;
ListNode *newP = new ListNode;
_size++;
newP->digit = newDigit;
newP->visited = false;
newP->next = _head;
_head = newP;
}
//Check for the digit 0
ListNode *prevPos = _head;
ListNode *curPos = _head->next;
for (int count = 0; count < MAX; count++) {
if (prevPos->digit == 0) {
_isValid = false;
break;
}
else {
prevPos = curPos;
curPos = curPos->next; //Bad access/segmentation fault here!
}
}
#ifndef RUNAROUND_H
#define RUNAROUND_H
class RunAroundChecker
{
private:
struct ListNode{
int digit; //store a single digit
bool visited; //have we visited this digit?
ListNode *next;
};
//Note that we can also wraps {digit, visited} into a single
//"item" package (e.g. through the use of pair clss), then the
// ListNode will have a consistent representation of {item, next}.
ListNode* _head;
int _size;
bool _runAround; //whether this is a run around number
bool _isValid; //whether the number is valid to be a run around number
public:
RunAroundChecker( int number );
//Pre: Takes in a positive number
//Post: The number is split into digits and stored internally
// In this case, as a linkedlist.
// The check of RunAround property should also be performed.
bool isRunAround();
//Pre: None. (the constructor will split + check the number)
//Post: return whether this is a run around number
void print();
//Pre: None.
//Post: Print the digits stored and the run around property.
};
#endif
#include <iostream>
#include <string>
#include "RunAround.h"
#define MAX 9
usingnamespace std;
RunAroundChecker::RunAroundChecker( int number )
//Pre: Takes in a positive number
//Post: The number is split into digits and stored internally
// In this case, as a linkedlist.
// The check of RunAround property should also be performed.
{
_head = NULL;
_size = 0;
_runAround = true;
_isValid = true;
//Split the digits and store in a linked list
while (number != 0) {
int newDigit = number % 10;
number /= 10;
ListNode *newP = new ListNode;
_size++;
newP->digit = newDigit;
newP->visited = false;
newP->next = _head;
_head = newP;
}
//Check for the digit 0
ListNode *prevPos = _head;
ListNode *curPos = _head->next;
for (int count = 0; count < MAX; count++) {
if (prevPos->digit == 0) {
_isValid = false;
break;
}
else {
prevPos = curPos;
curPos = curPos->next; //Bad access/segmentation fault here!
}
}
//Uniqueness check
ListNode *conductor1 = _head;
ListNode *conductor2 = conductor1->next;
while (conductor2 != NULL) {
int targetDigit = conductor1->digit;
for (int pos = 0; pos < _size; pos++) {
if (conductor2->digit == targetDigit) {
_isValid = false;
break;
}
conductor1 = conductor2;
conductor2 = conductor2->next;
}
}
//Run around check
if (!_isValid) {
_runAround = false;
}
else {
ListNode *currentPosition = _head;
int currentDigit = currentPosition->digit;
while (currentPosition->digit != 0) {
for (int spot = 0; spot < currentDigit; spot++) {
if (currentPosition->next == NULL) { //If we're at the end of the list, wrap back to the beginning
currentPosition = _head;
}
else {
currentPosition = currentPosition->next;
}
}
currentPosition->visited = true;
currentDigit = currentPosition->digit;
currentPosition->digit = 0; //Replace the digit landed on with 0
}
if (_head->visited == false) {
_runAround = false; //If first "visited" is false, number is not a runaround number
}
else {
for (currentPosition = _head->next; currentPosition != NULL; currentPosition = currentPosition->next) {
if (currentPosition->visited == false) { //If any "visited" is false, number is not a runaround number
_runAround = false;
break;
}
else {
_runAround = true;
}
}
}
}
}
bool RunAroundChecker::isRunAround()
//Pre: None. (the constructor will split + check the number)
//Post: return whether this is a run around number
{
return _runAround;
}
void RunAroundChecker::print()
//Pre: None.
//Post: Print the digits stored and whether the digits are visited
{
ListNode* cur;
for (cur = _head; cur != NULL; cur = cur->next){
cout << cur->digit << "[" << cur->visited << "] -> ";
}
cout << endl;
}