C++ Stack Implementation (Occasional Seg Fault)

I'm trying to figure out a problem with my program.

It works 75% of the time, and when pushing an item to a new stack ADT it will occasionally seg fault. This is confusing to me, because I'm used to things either seg-faulting 100% of the time, or not at all. I'm not sure why it would only happen sometimes.

I'm hoping someone can look into my code and give me an indication of what is going wrong to cause this problem.

Here is the relevant function. Let me know if anyone needs to see more of the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int Stack::push(const Route & to_add)
{
  if(!head)
  {
    cout << "Pushing to start of new stack." << endl;
    head = new s_Node;
    head->route_leg = new Route[MAXSTACK];
    head->next = NULL;
    top_index = 0;
    head->route_leg[0].copy_route(to_add);
    ++top_index;
    return 1;
  }

...
Last edited on
The error is elsewhere. Obviously! :-)
Last edited on
Something really awful in copy_route might be releasing demons into your operating system.
I'll check in the copy_from function... not sure what it could be though.

if anyone can see anything I'm missing here:

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
//Function to copy data into an entry in a node.
int Route::copy_route(const Route & copy_from)
{
  if (name) //Clears any existing garbage.
    delete [] name;
  if (notes) //Clears any existing garbage.
    delete [] notes;
  if (traffic) //Clears any existing garbage.
    delete [] traffic;

  name = notes = traffic = NULL; //Clears out everything.

  if(copy_from.name) //If there is information in the name.
  {
    name = new char[strlen(copy_from.name)+1]; //Dynamic allocate.
    strcpy (name, copy_from.name); //Copy.
  }
  else
    return 0;

  if (copy_from.notes) //If there is information in the notes.
  {
    notes = new char[strlen(copy_from.notes)+1]; //Dynamic allocate.
    strcpy (notes, copy_from.notes); //Copy.
  }
  else
    return 0;

  if (copy_from.traffic) //If there is information in the traffic.
  {
    traffic= new char[strlen(copy_from.traffic)+1]; //Dynamic allocate.
    strcpy (traffic, copy_from.traffic); //Copy.
  }
  else
    return 0;

  length = copy_from.length;

  return 1; //Return success.
}
Last edited on
You need to post the whole thing and give us some input so we can run it.
Don't guess about the "relevant" parts.
If it's too much to post here, put it somewhere else as a zip file and link to it here.
header.h

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
//Preprocessing directives.
#include <iostream>
#include <cctype>
#include <cstring>

using namespace std;

//Const int declaration for max queue size and max stack size.
const int MAX = 3; //Set max route size to 10.
const int MAXSTACK = 1; //Set max stack size to 5, guaranteeing 2dynamic stacks

//Class implementation for route object.
class Route
{
  public:
    Route(void); //Constructor.
    ~Route(void); //Deconstructor.
    //Function to create route, takes in all info from user/client.
    int create_route(char*name, char*notes, char*traffic, int length);
    //Function to display data members.
    void display(void);
    //Function to copy data members to calling routine.
    int copy_route(const Route & copy_from);
    //Function to retrieve a match inputted from user.
    int retrieve(char * match, Route&found);
    //Function to delete the dynamic memory created.
    void del_route();

  private:
    char *name; //Dynamic array of characters for the route name.
    char *traffic; //Dynamic array of characters for traffic.
    char *notes; //Dynamic array for route notes.
    int length; //Set int for length of route.
};

//Struct for queue node.
struct q_Node
{
  Route route_leg; //Allocate an instance of Route
  q_Node * next; //Set a next pointer.
};

//Class implementation for the queue.
class Queue
{
  public:
    Queue(void); //Constructor
    ~Queue(void); //Deconstructor
    int enQueue(const Route & to_add); //Enqueue to the CLL, taking in Route
    int deQueue(); //Dequeue from the CLL.
    int display(); //Display the CLL.
    bool isEmpty(); //Check if the CLL is empty.
    bool isFull(); //Check if the CLL is full.

  private:
    q_Node *rear; //Set a rear pointer for the end of the CLL.
    q_Node *front; //Set a front pointer for the front of the CLL.
    int count; //Set a count variable to manage number of nodes.
};

//Struct implementation for a stack node.
struct s_Node
{
  Route * route_leg; //Set a dynamic array of route objects.
  s_Node * next; //Set a pointer to next.
};

//Implementation for stack class.
class Stack
{
  public:
    Stack(void); //Constructor
    ~Stack(void); //Deconstructor
    int push(const Route & to_add); //Push to top of stack, taking a Route obj
    int pop(void); //Pop from top of the stack.
    int peek(); //Peek at top of the stack.
    int display(void); //Display the stack.
    bool isEmpty(); //Check if the stack is empty.

  private:
    s_Node *head; //Set head pointer.
    int top_index; //Set index for top of the stack.
};


//Generic function prototypes.
void menu(); //Function for main menu.
void welcome(); //Function for welcome message.
bool again(); //Function to ask the user to enter another route entry. 


stack.cpp
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
#include "header.h"

//Constructor for stack ADT.
Stack::Stack()
{
  head = NULL;
  top_index = -1;
}

//Deconstructor for stack ADT.
Stack::~Stack()
{
  s_Node *temp; //Create a temporary stack node pointer.
  while (head) //While loop while there is head data.
  {
    temp = head->next; //Set temp to head's next.
    delete [] head->route_leg; //Delete dynamically allocated array.
    delete head; //Delete head.
    head = temp; //Link head back to head's next.
  }
  temp = NULL; //Clear temp pointer.
}

//Function to check if the stack is empty.
bool Stack::isEmpty()
{
  return (top_index < 0); //Returns a bool based on if top_index is less than 0.
}

//Function to display the contents of the stack.
int Stack::display(void)
{
  if(isEmpty()) //Check if the stack is empty.
    return 0; //Exit

  s_Node * temp = head; //Set a temporary pointer to head.
  int top = top_index; //Set a temporary int to top_index.

  for (int i = top-1; i >=0; --i) //Loop to display from top-1.
  {
    temp->route_leg[i].display(); //Call to entry_display function.
  } //End for loop.

  while (temp->next) //If there's a head->next, i.e. another array.
  {
      temp = temp->next; //Traverse head.
      top = MAXSTACK; //Reset top int to the max of a stack.
      for (int i = top-1; i >=0; --i) //Loop to display from top-1.
      {
        temp->route_leg[i].display(); //Call to entry_display function.
      } //End for loop.
  } //End while temp->next.

  return 1; //Return success.
}

//Function to peek at the top of the stack.
int Stack::peek()
{
  if (isEmpty()) //Call to check if the stack is empty.
    return 0; //Return 0 if the stack is empty.

  else //Else, the stack is not empty.
    head->route_leg[top_index-1].display(); //Call to display top of stack.
    return 1; //Return success.
}

//Function to push a route entry to the top of the stack.
int Stack::push(const Route & to_add)
{
  //If there is no head, stack is empty, create a new node and arrays.
  if(!head)
  {
    head = new s_Node; //Head = new stack node.
    head->route_leg = new Route[MAXSTACK]; //Setup array to max size.
    head->next = NULL; //Set head's next to NULL.
    top_index = 0; //Set top index to 0.
    head->route_leg[0].copy_route(to_add); //Copy in entry into [0]
    ++top_index; //Increment top_index.
    return 1; //Return success.
  }

  //If there is an existing stack and we've not hit max entries.
  if(top_index < MAXSTACK)
  {
    head->route_leg[top_index].copy_route(to_add); //Populate at top of stack.
    ++top_index; //Increment top of stack counter.
    return 1; //Return success.
  }

  //If there is an existing stack and we're at max entries.
  if (top_index == MAXSTACK)
  {
    top_index = 0;
    s_Node * temp = new s_Node; //Set a new temporary stack pointer.
    temp->route_leg = new Route[MAXSTACK]; //Set dynamic arrays to MAX
    temp->route_leg[0].copy_route(to_add); //Copy in entry into first position.
    temp->next = head; //Set top->next to head, linking to the previous stack.
    head = temp; //Set temp to head.
    ++top_index; //Increment top index.
    //temp = NULL; //Clear temporary pointer.
    return 1; //Return success.
  }

  return 0; //Return failure if adding to stack failed any above.
}

//Function to pop the top entry off the stack.
int Stack::pop(void)
{
  if (isEmpty()) //If the stack is empty.
    return 0; //Return failure.

  if (top_index > 1 && !head->next) //If the stack exists and top_index is not at 1.
  {
    cout << "Removing element, and there is no other stack." << endl;
    cout << "Debug: Top_Index = " << top_index << endl;
    --top_index; //Decrement top index.
    return 1; //Return success.
  }

  //If the stack exists and top_index is 1, meaning last position is in 0.
  //And there exists another array in the stack.
  if (top_index == 1 && head->next)
  {
    cout << "Removing, and there is a next." << endl;
    cout << "Debug: Top_Index = " << top_index << endl;
    --top_index; //Decrement top_index to 0.
    s_Node * temp = head; //Create a temporary pointer.
    head = head->next; //Set head to head->next.
    delete [] temp->route_leg; //Delete the temporary dynamic array.
    delete [] temp; //Delete the temporary node.
    top_index = MAXSTACK; //Reset top_index to max_stack.

    return 1; //Return success.
  } //End if loop.

  //If the stack exists and top_index is 1, meaning last position is in 0.
  //And there is no additional stack arrays after this one.
  else if (top_index == 1 && !head->next)
  {
    cout << "Removing, and there is no other stack." << endl;
    cout << "Debug: Top_index = " << top_index << endl;
    --top_index; //Decrement top index.
    delete [] head->route_leg; //Delete the dynamic array.
    delete head; //Delete head.
    head = NULL; //Set head to NULL.
    top_index = -1; //Set top_index to -1.

    return 1; //Return success.
  }

  return 0; //Return failure if popping from the stack failed.
}
queue.cpp
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
#include "header.h"

//Constructor for the queue.
Queue::Queue()
{
  front = rear = NULL; //Set front and rear pointers to NULL.
  count = 0; //Set entry counter to 0.
}

//Deconstructor for the queue.
Queue::~Queue()
{
  cout << "DEBUG: Calling destructor." << endl;

  if(!front) //If there is no queue.
    return; //Exit constructor.

  q_Node * temp = front; //Set a temporary pointer for front of queue.
  rear->next = NULL; //Break the circular linked list.

  while (front) //While the circular list exists.
  {
    temp = front->next; //Set temp to front's next.
    front->route_leg.del_route(); //Run deletion of dynamic elements.
    delete front; //Delete the node.
    front = temp; //Link up to front's next.
  } //End while loop.
}

//Function to add an element to the queue. Takes in a Route object as an arg.
int Queue::enQueue(const Route & to_add)
{
  q_Node * temp = new q_Node; //Set a new temporary q_Node pointer.
  temp->route_leg.copy_route(to_add); //Copy in the data
  temp->next = NULL; //Set temp's next to NULL.

  if (front == NULL) //If there is no CLL.
  {
    front = rear = temp; //Set front and rear to the temporary node.
    ++count; //Increment entry count.
    return 1; //Return success.
  }

  else //There IS a CLL.
  {
    rear->next = temp; //Set rear->next to the new node.
    rear = temp; //Set the new rear as the new node.
    ++count; //Increment counter.
    temp = NULL; //Clear temp pointer.
    rear->next = front; //Link rear to front.
    return 1; //Return success.
  }

  return 0; //Return failure if adding to the CLL failed.
}

//Function to remove an element from the CLL, takes no arguments.
int Queue::deQueue()
{
  if(isEmpty()) //If there is no list, return 0.
    return 0;

  if(front == rear) //If there is a list, but only 1 item.
  {
    delete(front); //Delete the node.
    front = NULL; //Set front pointer to NULL.
    rear = NULL; //Set rear pointer to NULL.
    --count; //Decrement counter.
    return 1; //Return success.
  }

  else //There is a list, but more than one item.
  {
    q_Node * temp = front; //Set a temp pointer to front.
    front = front->next; //Set front to front's next.
    rear->next = front; //Set rear to the new front.
    temp->route_leg.del_route(); //Delete dynamic elements in the node.
    delete temp; //Delete the temporary node.
    --count; //Decrement count.
    return 1; //Return success.
  }

  return 0; //Return failure if removal from CLL failed.
}

//Function to display the contents of the CLL.
int Queue::display()
{
  if (isEmpty()) //If the CLL is empty.
    return 0; //Return failure.

  if(front == rear) //If the CLL exists and there is only 1 node.
  {
    front->route_leg.display(); //Display the first node.
    return 1; //Return success.
  }

  else //The CLL exists and there is more than one node.
  {
    q_Node * temp = front; //Set a temp pointer to front of CLL.
    do{ //Run loop until were back to the front.
      temp->route_leg.display(); //Display route information.
      temp = temp->next; //Traverse pointer.
    }while(temp != front); //End loop when were back to front.
  }

  return 0; //Return failure if the display fails.
}

//Function to check if the queue is empty.
bool Queue::isEmpty()
{
  if (!front) //If there is no front element, or the count = 0.
    return 1; //Return true - list is empty.

  else //If there is a front, or count > 0.
    return 0; //Return false - list is not empty.
}

//Function to check if the queue is full.
bool Queue::isFull()
{
  if (count == MAX) //If count = const MAX.
    return 1; //Return true - list is full.

  else //Else, count is less than MAX.
    return 0; //Return false - list is not full.
}


route.cpp
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
#include "header.h"

//Constructor for route. Empty as there are no dynamic elements or variables.
Route::Route()
{

}

//Deconstructor for route. Empty, as all deconstruction comes from calls.
Route::~Route()
{

}

//Called function to delete dynamic elements as nodes are deleted.
void Route::del_route()
{
  delete [] name; //Clear dynamic name.
  delete [] traffic; //Clear dynamic traffic.
  delete [] notes; //Clear dynamic notes.
}

//Function to display route entry contents.
void Route::display()
{
  cout << "\nRoute name: "<< name << endl;
  cout << "Route length: " << length << " miles." << endl;
  cout << "Route traffic: " << traffic << endl;
  cout << "Route notes: " << notes << endl;
}

//Function to set data to the entry.
int Route::create_route(char*input_name, char*input_notes,
                        char*input_traffic, int len)
{
  name = input_name; //Copy input variable into entry variable
  notes = input_notes; //Copy input variable into entry variable.
  traffic = input_traffic; //Copy input variable into entry variable.
  length = len; //Copy input variable into entry variable.

  return 1;
}

//Function to copy data into an entry in a node.
int Route::copy_route(const Route & copy_from)
{
  if (name) //Clears any existing garbage.
    delete [] name;
  if (notes) //Clears any existing garbage.
    delete [] notes;
  if (traffic) //Clears any existing garbage.
    delete [] traffic;

  name = notes = traffic = NULL; //Clears out everything.

  if(copy_from.name) //If there is information in the name.
  {
    name = new char[strlen(copy_from.name)+1]; //Dynamic allocate.
    strcpy (name, copy_from.name); //Copy.
  }
  else
    return 0;

  if (copy_from.notes) //If there is information in the notes.
  {
    notes = new char[strlen(copy_from.notes)+1]; //Dynamic allocate.
    strcpy (notes, copy_from.notes); //Copy.
  }
  else
    return 0;

  if (copy_from.traffic) //If there is information in the traffic.
  {
    traffic= new char[strlen(copy_from.traffic)+1]; //Dynamic allocate.
    strcpy (traffic, copy_from.traffic); //Copy.
  }
  else
    return 0;

  length = copy_from.length;

  return 1; //Return success.
}

//Function to retrieve an entry.
int Route::retrieve(char*match, Route&found)
{
  if (!name || !match)
    return 0;

  if (!strcmp(name, match))
  {
    if(found.name)
      delete [] found.name;
    if(found.notes)
      delete [] found.notes;
    found.name=found.notes=NULL;

    found.name = new char[strlen(name)+1];
    strcpy(found.name, name);

    found.notes = new char[strlen(notes)+1];
    strcpy(found.notes, notes);

    return 1;
  }

  return 0;
}
main.cpp
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
#include "header.h"

int main()
{
  int choice = 0; //Variable declaration for switch choice.
  int route_choice = 0; //Variable for selecting a simulated.
  bool exit = false; //Variable declaration for exit condition.

  Route to_add; //Setup an instance of the first route.
  Queue my_route; //Implement a Queue
  Queue my_route2; //Implement second route.
  Stack route_back; //Implement a Stack.
  Stack route_back2; //Implement second return.

  char name[100];   //Variable declaration for route_name
  char notes[100];  //Variable declaration for route_notes
  char traffic[100]; //Variable declaration for traffic_notes
  int length = 0; //Variable declaration for route length.

  do{ //Begin do-while loop for switch.

    welcome(); //Display welcome message.
    menu(); //Display main menu.
    cin >> choice; //Prompt user for switch choice.
    cin.ignore(100,'\n'); //Clear input buffer.

    switch(choice) //Begin switch.
    {

    default: //Set default condition for invalid choice.
      cout << "Invalid choice." << endl;
      break;

    case 1: //Create a primary route.
      do{if(my_route.isFull()) //If the route is full, break.
          {cout << "There is no more room." << endl; break;}
        if(my_route.isFull()) //If route is full, break.
        {
            cout << "There is no more room." << endl;
            return 0;
        }
        //Receive input from user. Store into static temporary.
        cout << "Enter route name/desc:" << endl;
        cin.get(name, 100); cin.ignore(100,'\n');
        cout << "Enter route length in miles:" << endl;
        cin >> length; cin.ignore(100,'\n');
        cout << "Enter typical route traffic:" << endl;
        cin.get(traffic, 100); cin.ignore(100,'\n');
        cout << "Enter any route notes:" << endl;
        cin.get(notes, 100); cin.ignore(100,'\n');

        //Fill 'to_add' with data in create_route function.
        to_add.create_route(name,notes,traffic,length);
        //Enqueue 'to_add', adding it to the end of the queue.
        my_route.enQueue(to_add);
        //Push 'to_add', adding it to the top of the stack.;
        route_back.push(to_add);
      }while(again()); //Prompt user to enter another leg of the route.
      break;

    case 2: //Create a secondary route.
      do{if(my_route2.isFull()) //If the route is full, break.
          {cout << "There is no more room." << endl; break;}
        if(my_route2.isFull()) //If route is full, break.
        {
            cout << "There is no more room." << endl;
            return 0;
        }
        //Receive input from user. Store into static temporary.
        cout << "Enter route name/desc:" << endl;
        cin.get(name, 100); cin.ignore(100,'\n');
        cout << "Enter route length in miles:" << endl;
        cin >> length; cin.ignore(100,'\n');
        cout << "Enter typical route traffic:" << endl;
        cin.get(traffic, 100); cin.ignore(100,'\n');
        cout << "Enter any route notes:" << endl;
        cin.get(notes, 100); cin.ignore(100,'\n');

        //Fill 'to_add' with data in create_route function.
        to_add.create_route(name,notes,traffic,length);
        //Enqueue 'to_add', adding it to the end of the queue.
        my_route2.enQueue(to_add);
        //Push 'to_add', adding it to the top of the stack.;
        route_back2.push(to_add);
      }while(again()); //Prompt user to enter another leg of the route.
      break;

    case 3: //Display the primary route.
      if(my_route.isEmpty()) //If the route is empty, break.
        {cout << "There is no primary route." << endl;break;}
      cout << "Displaying the primary route:" << endl;
      my_route.display(); //Output the queue.
      break;

    case 4:
      if(my_route2.isEmpty()) //If the route is empty, break.
        {cout << "There is no alternate route." << endl;break;}
      cout << "Displaying the alternate route:" << endl;
      my_route2.display(); //Output the queue.
      break;

    case 5:
      if(route_back.isEmpty()) //if the stack is empty, break.
        {cout << "There is no primary return route." << endl;break;}
      cout << "\nDisplaying the return route." << endl;
      route_back.display(); //Output the stack.
      break;

    case 0: //If the user enters 0.
      exit = true; //Set exit condition true, exiting switch.
      break;
  } //switch.
  }while(!exit); //End do-while checking for exit condition.

  //Call destructors.
  route_back.~Stack(); //Destroy the first stack.
  route_back2.~Stack(); //Destroy the second stack.
  my_route.~Queue(); //Destroy the first route.
  my_route2.~Queue(); //Destroy the second route.

  return 0;
}

//Function to welcome the user to the test program.
void welcome()
{
  cout << "=============================================" << endl;
  cout << "Welcome the Route Planner Test Program\n" << endl;
}

//Function to outline the test conditions in the program.
void menu()
{
  cout << "Select a test condition from the following:" << endl;
  cout << "Test 1. Create a primary route." << endl;
  cout << "Test 2. Create an alternate route." << endl;
  cout << "Test 3. Display primary route." << endl;
  cout << "Test 4. Display alternate route." << endl;
  cout << "Test 5. Display primary return route." << endl;
  cout << "Test 6. Display secondary return route." << endl;
  cout << "Test 7. Dequeue a route segment." << endl;
  cout << "Test 8. Check first step in return trip." << endl;
  cout << "Test 9. Remove first leg of return trip." << endl;
  cout << "Test 10. SIMULATE JOURNEY TO AND FROM!" << endl;
  cout << "0. Exit test program." << endl;
}

//Function to prompt the user if they want to enter another leg.
bool again()
{
  char choice = 0;
  cout << "Again? (Y/N) " << endl;
  cin >> choice;
  cin.ignore(100,'\n');
  choice = toupper(choice);

  if(choice == 'Y')
  {
    return 1;
  }

  else
    return 0;
}
Can you give me an input sequence that causes a segfault?
char *name; //Dynamic array of characters for the route name.
char *traffic; //Dynamic array of characters for traffic.
char *notes; //Dynamic array for route notes.
So do you have a fantastic awesome reason why you're NOT using std::string here?

Because there is an awful lot of twiddly memory management in your code, and you only have to screw up once to bring the whole thing down.

1
2
3
4
  route_back.~Stack(); //Destroy the first stack.
  route_back2.~Stack(); //Destroy the second stack.
  my_route.~Queue(); //Destroy the first route.
  my_route2.~Queue(); //Destroy the second route. 

And no, the compiler does this for you.
I think it was maybe on my compiler end... it doesn't do it from a different system.

And salem c - its an assignment, and from the intent its to teach us what the string class is doing from our own creations.
string class

But you aren't using the string class, that's the problem.
You are using raw char arrays.
But if you must use raw char arrays because of your assignment, then you aren't doing it correctly.
If it segfaults on one system but not on another, that still indicates a serious problem.
It's in the nature of "undefined behavior" to do that.
There is definitely an error in your code.
Yes, we are not allowed to use the string class.

And - ok, what in the use of raw char arrays am I doing incorrectly?

Why bother responding to a request for assistance if your assistance consists of:
"You aren't using a predefined class, so thats a problem."
"You are doing something wrong, but I won't tell you what."
"There's an error in what your doing, but I won't tell you what, or why."
Last edited on
> and from the intent its to teach us what the string class is doing from our own creations.
If the indent is to teach you to run a marathon, then your tutors approach to creating a level playing field is to begin by breaking everyone's legs, and then teaching you how to hobble.

You might learn how to overcome frustration and futility, but it isn't going to make you a better programmer.

1
2
3
4
5
6
7
//Function to set data to the entry.
int Route::create_route(char*input_name, char*input_notes,
                        char*input_traffic, int len)
{
  name = input_name; //Copy input variable into entry variable
  notes = input_notes; //Copy input variable into entry variable.
  traffic = input_traffic; //Copy input variable into entry variable. 

Wrong - all of these need your new + strcpy combo.

If you used std::string's throughout, then assignment would just work.
And your Route::copy_route() function would be 1 line long, not 40.


Last edited on
Thanks, I will give that a try.
Why bother responding to a request for assistance if your assistance consists of:
"You aren't using a predefined class, so thats a problem."
"You are doing something wrong, but I won't tell you what."
"There's an error in what your doing, but I won't tell you what, or why."

You didn't say you weren't allowed to use std::string, which is standard in C++. So the best advice is to use it.

It's not that I won't tell you what you're doing wrong, it's that you're such a fucking asshole that I don't want to help you.
I posted my code, and unprompted you refuse to provide assistance and only post condescending nonsense... so, thats on your end.
In route::copy_route(), you you return early, you don't set the length member. Does this make the instance inconsistent?


1
2
3
4
//Constructor for route. Empty as there are no dynamic elements or variables.
Route::Route()
{
}


All of the private members hold dynamic pointers. They must be initialized:
1
2
3
4
5
6
7
8
9
class Route
{
...
  private:
    char *name; //Dynamic array of characters for the route name.
    char *traffic; //Dynamic array of characters for traffic.
    char *notes; //Dynamic array for route notes.
    int length; //Set int for length of route.
};


Further, you should implement copy/assignment operators and the equivalent move operators, or you should declare them private to prevent the compiler defaults from being created and called.

I won't look further. Basically you need to be very careful about your memory management.
Thank you for your help!
Sarcasm and passive aggressive reaction in large doses. Ah, the wonders of modern Entitlementism.
Topic archived. No new replies allowed.