2

I'm currently trying to solve coding challenge for studying for my intro c++ course and I'm just trying to understand the segmentation fault error I'm getting.

I'm writing a given function to insert nodes at the tail of a linked list. The idea is that given an input of integers the first input would be considered part of the end of the list because it's pointer member variable would be nullptr. Afterwards, all other inputs would have to be appended so that their insertion occurs before that null node.

Here's my first part of the function:

SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) {


if(head == nullptr) //if the list is empty
{
    head -> next = new SinglyLinkedListNode(data);
    return head;
}

return head;

} 

however this part of the function is giving me a segmentation fault error:

head -> next = new SinglyLinkedListNode(data);

These are the class declarations:

#include <bits/stdc++.h>

using namespace std;

class SinglyLinkedListNode {
 public:
    int data;
    SinglyLinkedListNode *next;

    SinglyLinkedListNode(int node_data) {
        this->data = node_data;
        this->next = nullptr;
    }
     };

class SinglyLinkedList {
public:
    SinglyLinkedListNode *head;

    SinglyLinkedList() {
        this->head = nullptr;
    }

 };

and Main:

int main()
{
ofstream fout(getenv("OUTPUT_PATH"));

SinglyLinkedList* llist = new SinglyLinkedList();

int llist_count;
cin >> llist_count;
cin.ignore(numeric_limits<streamsize>::max(), '\n');

for (int i = 0; i < llist_count; i++) {
    int llist_item;
    cin >> llist_item;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    SinglyLinkedListNode* llist_head =
    insertNodeAtTail(llist->head, llist_item);
    llist->head = llist_head;
}

print_singly_linked_list(llist->head, "\n", fout);
fout << "\n";

free_singly_linked_list(llist->head);

fout.close();

return 0;
 }

I was thinking that :

 head -> next = new SinglyLinkedListNode(data);

would create a new node with the data argument as it's member data and then the current head node would point to that list.

I would like to know why this segmentation fault is occurring. Also, I cannot change any of the class declaration or constructors since that's how they are given in the challenge.

GDB Trace:

Reading symbols from solution...done.
[New LWP 22279]
Core was generated by `solution'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000400eea in insertNodeAtTail (head=<optimized out>, 
data=<optimized out>) at solution.cc:62
62          head -> next = new SinglyLinkedListNode(data);
#0  0x0000000000400eea in insertNodeAtTail (head=<optimized out>, 
data=<optimized out>) at solution.cc:62
#1  0x0000000000400c2e in main () at solution.cc:88
Papaya-Automaton
  • 239
  • 1
  • 13
  • 1
    note: https://stackoverflow.com/q/31816095/5470596 – YSC Nov 14 '18 at 16:11
  • By the way, modern compilers with optimizations enabled will instead do invalid opcode trap. – SergeyA Nov 14 '18 at 16:15
  • 2
    Please [edit] your question to show us what kind of debugging you've done. I expect you to have run your [mcve] within Valgrind or a similar checker, and to have investigated with a debugger such as GDB, for example. Ensure you've enabled a full set of compiler warnings, too. What did the tools tell you, and what information are they missing? And read Eric Lippert's [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Toby Speight Nov 14 '18 at 16:20
  • 1
    You really ought to avoid `using namespace std` - it is a bad habit to get into, and [can silently change the meaning of your program](/q/1452721) when you're not expecting it. Get used to using the namespace prefix (`std` is intentionally very short), or importing *just the names you need* into the *smallest reasonable scope*. It's especially pernicious in header files, as you now inflict the problem on every source file that includes the header! – Toby Speight Nov 14 '18 at 16:21

2 Answers2

5

Because dereferencing a null pointer (head IS null) is undefined behavior whose consequence can be a segmentation fault:

if(head == nullptr) //if the list is empty
{
    head -> next = new SinglyLinkedListNode(data);
YSC
  • 34,418
  • 7
  • 80
  • 129
0

Head is null. You cannot access the 'next' field of a null object.

if(head == nullptr) //if the list is empty
{
    head = new SinglyLinkedListNode(data);
    return head;
}
return insertNodeAtTail(head->next, data)