A section of one of my assignments asks for me to recursively search through a list to see if a double is in it. It prints a string about whether it is in the list or not, but after it finishes the cycle it crashes and says there was a segmentation fault. The following is the isolated section of the code that uses the recursive method.
class Header
{
protected:
//Create the struct for the list
struct ListNode {
double x;
ListNode *next;
ListNode(double v1, ListNode *n1 = nullptr) {
double x = v1;
next = n1;}
};
ListNode *head;
public:
Header()
{head = nullptr;}
//Add doubles to the list
void add(double var) {
if(head == nullptr)
{head = new ListNode(var);}
else {
ListNode *nodePtr = head;
while(nodePtr->next != nullptr)
{nodePtr = nodePtr->next;}
nodePtr->next = new ListNode(var);
}
}
//Call the function that performs the recursive function
void recursiveMember(double var) const
{recursiveMember(head, var);}
private:
//This is where the issue is
void recursiveMember(ListNode *aList, double var) {
if(aList == nullptr)
{cout << var << " is not in the list" << endl;}
if(var != aList->x)
{recursiveMember(aList->next, var);}
else
{cout << var << " is in the list" << endl;}
}
};
int main()
{
//Create the object
Header vars;
//Populate the object
vars.add(1.1);
vars.add(2.2);
vars.add(3.3);
//Call the recursive function
vars.recursiveMember(1.1);
vars.recursiveMember(.5);
return 0;
}
The program displays
1.1 is in the list
.5 is not in the list
Segmentation fault (core dumped)
This would not necessarily be a problem, but there is some other functionality that I need to perform after and the segfault causes the program to crash before performing that.
I was using the gdb
debugger to isolate the error causing code, which is if(var != aList->x)
to implement the recursive function.
Is there something about recursion I am missing?
You need to return from the recursiveMember
function if aList
is nullptr
. Otherwise you are accessing invalid Nodes.
if(aList == nullptr)
{
cout << var << " is not in the list" << endl;
return;
}
Equivalently, you could enter the second if
branch conditionally
if(aList == nullptr)
{
cout << var << " is not in the list" << endl;
}
else if(var != aList->x)
// ...
Also, in your ListNode
constructor, you are not assigning the data correctly
ListNode(double v1, ListNode *n1 = nullptr) {
double x = v1; // this x is a local variable
next = n1;
}
Instead, you need to assign to the member
x
.
ListNode(double v1, ListNode *n1 = nullptr) {
x = v1; // this x is the member
next = n1;
}
For starters, you may not call a non-constant member function from a constant member function. So the function shall be declared at least like
void recursiveMember(ListNode *aList, double var) const;
Secondly, the private member function accepts as argument a pointer to the head node si it should be declared as a static member function
static void recursiveMember(ListNode *aList, double var);
And thirdly the both functions private and public shall not to output any message. It is the caller of the functions decides whether to output anything. The function shall return a boolean value.
So the first function should be declared like
bool recursiveMember( double var ) const
{
return recursiveMember( head, var);
}
and the second function should be declared like
static bool recursiveMember( const ListNode *aList, double var);
Further, if the current value of the pointer aList
is equal to nullptr
nevertheless you are trying to use it to access memory in the second if statement
if(var != aList->x)
{recursiveMember(aList->next, var);}
That is there is no return from the function in the case when aList
is equal to nullptr
.
if(aList == nullptr)
{cout << var << " is not in the list" << endl;}
The function should be defined the following way
static bool recursiveMember( const ListNode *aList, double var )
{
if ( aList == nullptr )
{
return false;
}
else if ( a:ist->var != var )
{
return recursiveMember( aList->next, var );
}
else
{
return true;
}
}
And in main you should check the return value of the called function and output a corresponding message.
Pay attention to that within the constructor you are using the local variable x instead of the data member x
ListNode(double v1, ListNode *n1 = nullptr) {
double x = v1;
next = n1;}
There must be
ListNode(double v1, ListNode *n1 = nullptr) {
x = v1;
next = n1;}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.