Segmentation fault

closed account (ybq5Djzh)
How are segmentation faults fixed? I'm not understanding what to do!
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
#include <iostream>
#include <cstdio>
#include <cstring>
#include "Student_Class.h"
using namespace std;

void treeInsert (student *& root, char key[])
{
	char item[50];
	strcpy (item, root -> getName ());
	if (root == NULL)
	{
		root = new student (key);
	}
	else if (key < item)
	{
		treeInsert (root -> left, key);
	}
	else if (key > item)
	{
		treeInsert (root -> right, key);
	}
}

bool treeContains (student *root, char key[])
{
	char item[50];
	strcpy (item, root -> getName());
	if (root == NULL)
	{
		return false;
	}
	else if (key == item)
	{
		return true;
	}
	else if (key < item)
	{
		return treeContains (root -> left, key);
	}
	else if (key > item)
	{
		return treeContains (root -> right, key);
	}
}

void treeList (student *root)
{
	char item[50];
	strcpy (item, root -> getName ());
	if (root != NULL)
	{
		treeList (root -> left);
		cout << item << endl;
		treeList (root -> right);
	}
}

int main()
{
	student *s; //Pointer to the Student object
	FILE *stud; //File pointer
	int i, j, k; //Loop variables
	char lineStr[1000]; //To store text of each line
	char temp[100]; //To store each value for a variable before pushing it to the tree
	char out[100]; //To fix last value errors
	stud = fopen ("Random.txt", "r");
	s = NULL;
	while (!feof (stud))
	{
		fgets (lineStr, 1000, stud);
		i = 0;
		j = 0;
		for (k = 0; temp[k] != '\0'; k++)
		{
			temp[k] = ' ';
		}
		while (lineStr[i] != ',')
		{
			temp[j++] = lineStr[i++];
		}
		temp[j] = '\0';
		if (treeContains (s, temp))
		{
			cout << "Duplicate\n";
			continue;
		}
		if (strcmp (temp, out) == 0)
		{
			continue;
		}
		treeInsert (s, temp);
		strcpy (out, temp);
	}
	treeList (s);
	return 0;
}


the Student_Class.h file

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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
//CS101 Course Project, Autumn Semester, Lab Group 542
//File Student_Class.h

class student
{
	private:
		char name[50];
		char rollNo[10];
		int mobile;
		char email[40];
		int hostel;
		int roomNo;
		char dept[3]; //Just a 2 letter dept code e.g. CS for Computer Science, CL for Chemical etc., one extra null
		int dobDate; //DOB - Date
		int dobMonth; //DOB - Month
		int dobYear; //DOB - Year
		int courseProg; //Type of programme e.g. 4 year B. Tech., 5 year B. Tech. + M. Tech. Dual Degree, 2 year M. Sc. Refer Course_Prog.txt for the codes
		int semOfStudy; //1st semester, 2nd semester etc.
		int yearOfJoin; //Which year the student joins
		int noOfCourses; //Number of courses the student has taken
		char course[10][6]; //5 letter course code e.g. MA105, CS101; one extra null
		int marks[10]; //Marks attained in each course
		char grade[10][3]; // AA, AB etc., one extra null
		int maxCredit[10]; //Credits alloted for each course
		float spi[10];
		float cpi;
		float attendance[10]; //Percentage of attendance in each course. Hence, float.
		char password[20]; //Max length of password is 20 characters

	public:
		student *left;
		student *right;

		void setName (char nm[])
		{
			strcpy (name, nm);
		}

		char* getName ()
		{
			return name;
		}

		void setRollNo (char roll[])
		{
			strcpy (rollNo, roll);
		}

		void getRollNo (char roll[])
		{
			strcpy (roll, rollNo);
		}

		void setMobile (int mob)
		{
			mobile = mob;
		}

		int getMobile ()
		{
			return mobile;
		}

		void setEmail (char mail[])
		{
			strcpy (email, mail);
		}

		void getEmail (char mail[])
		{
			strcpy (mail, email);
		}

		void setHostel (int host)
		{
			hostel = host;
		}

		int getHostel ()
		{
			return hostel;
		}

		void setRoomNo (int room)
		{
			roomNo = room;
		}

		int getRoomNo ()
		{
			return roomNo;
		}

		void setDept (char dep[])
		{
			strcpy (dept, dep);
		}

		void getDept (char dep[])
		{
			strcpy (dep, dept);
		}

		void setDobDate (int ddate)
		{
			dobDate = ddate;
		}

		int getDobDate ()
		{
			return dobDate;
		}

		void setDobMonth (int dmonth)
		{
			dobMonth = dmonth;
		}

		int getDobMonth ()
		{
			return dobMonth;
		}

		void setDobYear (int dyear)
		{
			dobYear = dyear;
		}

		int getDobYear ()
		{
			return dobYear;
		}

		void setCourseProg (int prog)
		{
			courseProg = prog;
		}

		int getCourseProg ()
		{
			return courseProg;
		}

		void setSemOfStudy (int sem)
		{
			semOfStudy = sem;
		}

		int getSemOfStudy ()
		{
			return semOfStudy;
		}
		
		void setYearOfJoin (int year)
		{
			yearOfJoin = year;
		}
        
		int getYearOfJoin ()
		{
			return yearOfJoin;
		}

		void setNoOfCourses (int num)
		{
			noOfCourses = num;
		}

		int getNoOfCourses ()
		{
			return noOfCourses;
		}

		void setCourse (char crse[][6])
		{
			int i, j;
			for (i = 0; i < noOfCourses; i++)
			{
				strcpy (course[i], crse[i]);
			}
		}

		void getCourse (char crse[][6])
		{
			int i, j;
			for (i = 0; i < noOfCourses; i++)
			{
				strcpy (crse[i], course[i]);
			}
		}

		void setMarks (int mrks[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				marks[i] = mrks[i];
			}
		}

		void getMarks (int mrks[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				mrks[i] = marks[i];
			}
		}

		void setGrade (char grd[][3])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				strcpy (grade[i], grd[i]);
			}
		}

		void getGrade (char grd[][3])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				strcpy (grd[i], grade[i]);
			}
		}

		void setMaxCredit (int crdt[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				maxCredit[i] = crdt[i];
			}
		}

		void getMaxCredit (int crdt[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				crdt[i] = maxCredit[i];
			}
		}
		
		void setSpi (float subjSpi[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				spi[i] = subjSpi[i];
			}
		}
        
		void getSpi (float subjSpi[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				subjSpi[i] = spi[i];
			}
		}

		void setCpi (float subjCpi)
		{
			cpi = subjCpi;
		}

		float getCpi ()
		{
			return cpi;
		}

		void setAttendance (float attend[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				attendance[i] = attend[i];
			}
		}

		void getAttendance (float attend[])
		{
			int i;
			for (i = 0; i < noOfCourses; i++)
			{
				attend[i] = attendance[i];
			}
		}

		void setPassword (char pwd[])
		{
			strcpy (password, pwd);
		}

		void getPassword (char pwd[])
		{
			strcpy (pwd, password);
		}
		
		student ()
		{
			left = NULL;
			right = NULL;
		}
		student (char key[])
		{
			strcpy (name, key);
			left = NULL;
			right = NULL;
		}
};


Please help!!
Check how you are accessing your arrays/pointers. Make sure you stay within the arrays size and don't use invalid pointers. I'm not gonna read through all that to check for those though, that's your job.
First question: Why aren't we using strings instead of c-style strings?

There are a lot of places I can see a segmentation fault generated looking over the code. Using c++ style string verses c-style strings would save a lot of headache, since you are misusing the c-style strings in your code to begin with.

The easiest way to find the segmentation faults is with a debugger or strategic code that outputs markers to standard out for where I am in the execution.
The point of classes is so that you don't have to do all that crap that you did up there.

1
2
3
4
5
6
7
8
9
		void setCpi (float subjCpi)
		{
			cpi = subjCpi;
		}

		float getCpi ()
		{
			return cpi;
		}


This is VBA programming; you don't have to put all of this in there, there are much cleaner and easier ways to assign variables.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void treeInsert (student *& root, char key[])
{
	char item[50];
	strcpy (item, root -> getName ()); //deferencing the pointer
	if (root == NULL)  //checking if it is a valid point
	{
		root = new student (key);
	}
	else if (key < item) //comparing pointers
	{
		treeInsert (root -> left, key);
	}
	else if (key > item)
	{
		treeInsert (root -> right, key);
	}
}
The first thing you need to do is to check if the pointer is valid.
Later you've got a problem because you are comparing pointers, not their contents. Also the copy to 'item' is unnecessary.

You should encapsulate that behaviour in classes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class bintree_node{
  friend class bintree;
private:
  student me;
  student *left, *right;
};

class bintree{
private:
  bintree_node root;
public:
  //all the functions to insert, delete, find students
  //you will be operating with nodes, but the user doesn't need to know that.
};
Then you will notice that your tree class shouldn't care if it is storing students, numbers, monsters, etc. so you will make it a template.

You really should review 'student' design.
There are a lot of things that shouldn't be in 'student' (like the credits of the courses) and others that could be encapsulated in other classes (like dates)
And ~260 LOC that don't do anything,

@ciphermagi: ¿could you expand your answer? ¿what ways are you talking about?
http://www.cplusplus.com/doc/tutorial/classes/

If you look under constructors and destructors in this page, you'll see how to build a constructor and a destructor. It doesn't quite give the same functionality as being able to use each of the variables independently, but if you wanted to do that, then there isn't really a clear purpose to having the class in the first place (Note: I said clear purpose...there are cases where individually changing variables in a class is appropriate). Classes and structs are designed to be implemented as objects, and this looks like it's being used as a complicated global variable container instead.
closed account (ybq5Djzh)
@ne555

Could you elaborate? I'm a novice and still learning. :)

@ciphermagi

I need to use each variable independently. If not the whole point of my project is lost.
As Azagaros says, build with debug symbols and use a debugger. It will catch the segFault and tell you exactly which line the code segFaults on. A segFault happens when you try to read or write memory that the operating system hasn't given you.
¿elaborate on what?
This is basically what you are doing
1
2
student *s = NULL;
s->getName(); //crash 


And to compare
1
2
//if (key == item) //key and item are pointers
if( strcmp(key, item) == 0 )
It would be easier if you use std::string
closed account (ybq5Djzh)
Thanks for the tip1!! And how to get a debugger?
Topic archived. No new replies allowed.