Segment Fault help.

So I have written a large program and I get it to run for a little bit but it has given me a segmentation fault. I think i`ve narrowed it down to my main.cc it runs welcome to friends managment and begin by enter username and it runs my test and then core dumps after that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	cout<<"Welcome to Friends Management.\n\n";
	cout<<"Begin by entering your username: ";
	cout<<"test"<<endl; // SEGMENT FAULT RADIUS
	getline(cin,username);
	filename = username + ".txt";
	fin.open(filename.c_str());
    if(!fin.fail())
	myfb.load(fin);
	fin.close(); // END SEGMENT FAULT RADIUS
	choice = 0;
	choice2 = 0;
	cutout = false;
        FBFriends original(myfb);


Here is my main.cc if you wish to see more.
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
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include "friend.h"
#include "fbfriends.h"
using namespace std;

int menu();
int menu2();

int main(){

    Friend myfriend;
    FBFriends myfb;
    string friendname;
    int choice,choice2;
    string username, filename;
    ifstream fin;
    ofstream fout;
    bool cutout;

	cout<<"Welcome to Friends Management.\n\n";
	cout<<"Begin by entering your username: ";
	cout<<"test"<<endl;//*
	getline(cin,username);
	filename = username + ".txt";
	fin.open(filename.c_str());
    if(!fin.fail())
	myfb.load(fin);
	fin.close();
	choice = 0;
	choice2 = 0;
	cutout = false;
        FBFriends original(myfb);

	while(choice != 9){
	    choice = menu();
	    switch(choice){
		case 1:	cin>>myfriend;
		       	myfb.start();
			myfb.insert(myfriend);
			break;
		case 2: myfb.show_all(cout);
			break;
		case 3: {myfb.start();
			choice2 = 0;
			while(myfb.is_item()&& choice2 <= 5){
			    cout<<myfb.current();
			    choice2 = menu2();
			    if(choice2 == 1)
				myfb.remove_current();
			    else if(choice2 == 2){
				if(!cutout)
				cin>>myfriend;
				if(myfb.is_friend(myfriend)) 
				cout<<"Already in list.\n";
				else
				myfb.insert(myfriend);
				cutout = false;
			    }
			    else if(choice2 == 3){
				if(!cutout)
				cin >> myfriend;
                               if(myfb.is_friend(myfriend))
                                cout<<"Already in list.\n";
                                else
				myfb.attach(myfriend);
				cutout = false;
			    }
			    else if (choice2 == 4){
				myfriend = myfb.current();
				myfb.remove_current();
				cutout = true;
				}
			    else if(choice2 == 5){
				myfb.advance();
			    }
			    else
				cout<<"Going back to main menu.\n";
			}
			break;
			}
		case 4: myfb.bday_sort();
			break;
		case 5:{
			cout<<"Enter the name of your friend:\n";
			if(cin.peek() == '\n') cin.ignore();
			getline(cin, friendname);
			myfriend = myfb.find_friend(friendname);
			cout<<myfriend<<endl;
			break;
			}
		case 6:	original.show_all(cout);
			break;
		default: break;
		} // bottom of the switch
	} // bottom of the while
	fout.open(filename.c_str());
        if(!fout.fail())
	    myfb.save(fout);
	else
	    cout<<"Unable to save data.\n";
	fout.close();

	cout<<"Come visit your friends again soon.\n";
return 0;
}
	
int menu(){
	int ans;
	cout<<"Choose from the options below:\n";
	cout<<"1 - Add a friend to the beginning of the list.\n";
	cout<<"2 - See all your friends.\n";
	cout<<"3 - Walk through the list, one friend at a time.\n";
	cout<<"4 - Sort your friends by birthday.\n";
	cout<<"5 - Find a friend so you can learn when they were born.\n";
	cout<<"6 - See the list you started with in today's session. \n";
	cout<<"9 - Leave the program.\n";
	cin>>ans;
    return ans;
}

int menu2(){
	int ans;
	cout<<"What would like to do with this friend?\n";
	cout<<"1 - Remove from the list.\n";
	cout<<"2 - Insert a new friend or cut-out friend before this friend.\n";
	cout<<"3 - Put a new friend or cut-out friend after this friend.\n";
	cout<<"4 - Cut this friend from the list to be inserted elsewhere.\n";
	cout<<"    If you want the friend earlier in the list you will need to start a new walk-through.\n";
	cout<<"5 - Advance to the next friend.\n";
	cout<<"6 - Return to main menu.\n";
	cin>>ans;
    return ans;
}
Last edited on
You're saying one of the following lines crashes, right?

1
2
3
4
5
6
	getline(cin,username);
	filename = username + ".txt";
	fin.open(filename.c_str());
	if(!fin.fail())
		myfb.load(fin);
	fin.close();


I'd take a guess and say it's your FBFriends::load(std::istream&) function that's causing the problem, as the other stuff seems rather standard.

To avoid headaches like this, I really suggest using a debugger. A debugger lets you step through your program with break points, or line by line, and you can get the state of every variable so that you know exactly when something is going wrong. If you have a modern IDE, such as Visual Studio, CodeBlocks, Eclipse, etc., they all have good debugging options.
Last edited on
From looking at it looks fine i`m still rather new at c++ but it looks good to me.

FBFriends.cc

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
#include "fbfriends.h"
#include <iostream>

FBFriends::FBFriends(){
data = new Friend[5];
used = 0;
capacity = 5;
current_index = -1;
}

FBFriends::~FBFriends(){
delete[] data;
}

FBFriends::FBFriends(const FBFriends &other){
*this = other;
}

void FBFriends::operator=(const FBFriends &other){
if(this == &other){
  return;
}
delete[] data;
capacity = other.capacity;
data = new Friend[capacity];
used = other.used;
for(int i = 0;i<used;i++){
  data[i] = other.data[i];
}
}

void FBFriends::start(){
current_index = 0;
}

void FBFriends::advance(){
if(current_index < used-1)
  current_index++;
}

Friend FBFriends::current(){
return data[current_index];
}

bool FBFriends::is_item(){
return current_index > 0 && current_index < used;
}

void FBFriends::remove_current(){
if(is_item()){
  for(int i = current_index;i<used-1;i++){
   data[i] = data[i+1];
  }
  used--;
}
}
void FBFriends::insert(const Friend &f){
if(!is_item()){
  return;
}
if(used >= capacity){
  resize();
}
for(int i = used;i>current_index;i--){
  data[i] = data[i-1];
}
data[current_index] = f;
}

void FBFriends::attach(const Friend &f){
if(used >= capacity){
  resize();
}
data[used++] = f;
}

void FBFriends::show_all(std::ostream &outs)const{
for(int i = 0;i<used;i++){
  outs<<data[i]<<' ';
}
}

Friend FBFriends::find_friend(const std::string &name)const{
for(int i = 0;i<used;i++){
  if(data[i].get_name() == name){
   return data[i];
  }
}
}

bool FBFriends::is_friend(const Friend &f)const{
for(int i = 0;i<used;i++){
  if(f == data[i]){
   return true;
  }
}

return false;
}

void FBFriends::load(std::istream &ins){ // THE PROBLEM??
Friend temp;
while(!ins.eof()){
  ins>>temp;
  attach(temp);
}
}

void FBFriends::save(std::ostream &outs){
for(int i = 0;i<used;i++){
  outs<<data[i]<<' ';
}
}

void FBFriends::bday_sort(){
Friend temp;
for(int i = 0;i<used;i++){
  for(int j = i+1;j<used;j++){
   if(data[i].get_bday() > data[j].get_bday()){
    temp = data[i];
    data[i] = data[j];
    data[j] = temp;
   }
  }
}
}

void FBFriends::resize(){
capacity = capacity + 5;
Friend *temp = new Friend[capacity];
for(int i = 0;i<used;i++){
  temp[i] = data[i];
}
delete[] data;
data = temp;
}
1
2
3
4
5
6
7
8
9
10
11
FBFriends::FBFriends(const FBFriends &other){
   *this = other;
}

void FBFriends::operator=(const FBFriends &other){
   if(this == &other){
      return;
   }
   delete[] data; //¿what's the value of `data' here?
   //...
}
make `data' a std::vector


if you need more help
http://www.eelis.net/iso-c++/testcase.xhtml
A testcase consisting of randomly copy&paste'd bits of code that you thought were relevant can obviously not reproduce the problem.
Last edited on
Main program line 29: If the condition is false, only line 30 is skipped. The way you've indented the code suggests that you want to skip the rest of the program. Add braces if necessary.

Overall, you've done a really good job of managing the memory yourself. Most beginners mess this up.

FBFriends::insert: You forgot to increment used.
FBFriends::is_item: This returns false when current_index==0. Should it?
FBFriends::find_friend doesn't return anything if name isn't found. I suggest that you change it to:
1
2
3
// Find a friend. If found, then copy the friend to "found" and return true.
// Otherwise leave "found" unchanged and return false.
bool FBFriends::find_friend(const std::string &name, Friend &found) const


bool FBFriends::is_friend: This should call find_friend. E.g.:
1
2
Friend dummy;
return find_friend(name, dummy);


FBFriends::load: eof() won't return true until you try to read past the end of file. So after reading the last friend, eof() will return true but ins>>temp will fail. Change lines 103 & 104 to:
while (ins >> temp) {
Also load() appends items rather than replacing the contents with what's in the file. In other words, if the FBFriends instance contains friends "Bud" and "Lou" before calling load(), it will still contain Bud and Lou after. Is this what you intended?

Please provide the definition for class Friend. It's possible that the crash is there.
So i deleted the delete data in my operator function and it fixed my segment fault but now there are other problems.

This is what you asked for.
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
#include<iostream>
#include<string>
#include "date.h"
#ifndef FRIEND_H
#define FRIEND_H


class Friend{
    public:
	Friend();
	std::string get_name()const;
	Date get_bday()const;
	bool operator == (const Friend& other)const;
	bool operator != (const Friend& other)const;
	void input(std::istream& ins);
	void output(std::ostream& outs)const;
    private:
	std::string name;
	Date bday;
};

std::istream& operator >>(std::istream& ins,Friend& f);
std::ostream& operator <<(std::ostream& outs,const Friend& f);

#endif 
> Overall, you've done a really good job of managing the memory yourself. Most
> beginners mess this up.
no, he messed up, that's the cause of the crash.


> So i deleted the delete data in my operator function and it fixed my segment
> fault but now there are other problems.
http://www.eelis.net/iso-c++/testcase.xhtml
also, «other problems» is not an error message
Problem 1
So this is what it my list is supposed to look like when i press 2.

Billy Gibbons
12/16/1949
Jimmy Page
1/9/1944
Jeff Beck
6/24/1944
George Harrison
2/25/1943
Eric Clapton
3/30/1945
Lindsey Buckingham
10/3/1949

what it ends up looking like when i press 2:
illy Gibbons 16/2/1949 immy Page 1944/9/1949 eff Beck 1944/24/1949 eorge Harrison 1943/25/1949 ric Clapton 1945/30/1949 indsey Buckingham 3/0/1949

---------------------------------------------------------------------------------------------------------
Problem 2

If choose 5 the cout pops up "enter the name of your friend" when i enter that it returns

terminate called after throwin an instance of 'std::bad_alloc'
what(): std::bad_alloc
aborted (core dumped)
---------------------------------------------------------------------------------------------------------
Problem 3

1 wont actually add the friend and option 3 and 4 dont even work.

---------------------------------------------------------------------------------------------------------

Rip project due at midnight today.
Last edited on
Did you fix the bug that ne555 pointed out in his first post? That's probably the cause of your crash.
what it ends up looking like when i press 2:
illy Gibbons 16/2/1949 immy Page 1944/9/1949 eff Beck 1944/24/1949 eorge Harrison 1943/25/1949 ric Clapton 1945/30/1949 indsey Buckingham 3/0/1949

Please provide the code for class Friend.
I have never made a vector so no I didn’t fix it yet.
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
#include "friend.h"
#include<sstream>

using namespace std;

Friend::Friend(){
name = "";
bday = Date();
}

std::string Friend::get_name()const{
	return name;
}

Date Friend::get_bday()const{
	return bday;
}
bool Friend::operator==(const Friend &f)const{
	return name == f.get_name() && bday == f.get_bday();
}

bool Friend::operator !=(const Friend &f)const{
	return !(*this == f);
}

void Friend::input(std::istream &ins){
	ins.ignore();
	getline(ins,name);
	ins.ignore();
	int d,m,y;
	string dt;
	getline(ins,dt);
	stringstream ss;
for(int i = 0;i<dt.length();i++){
  if(dt[i] == '/'){
   	ss<<" ";
  }else{
   	ss<<dt[i];
  }
}
ss>>d>>m>>y;
ss.clear();
bday = Date(d,m,y);
}

void Friend::output(std::ostream &ous)const{
	outs<<name<<"\t"<<bday;
}

std::ostream& operator<<(std::ostream &ous,const Friend &f){
	f.output(outs);
		return outs;
}

std::istream& operator>>(std::istream &ins,Friend &f){
	f.input(ins);
	return ins;
}
Thanks.

The reason your output truncates the first character is all those calls to ins.ignore() in Friend::input(). Assuming that the input format is:
Name
dd/mm/yyyy
Then you can remove lines 27 and 29. If the stream is at the end of the previous line when you call input(), then it's up the caller to position it to the right place.
It fixed the first letter do you know why its doing that to the numbers?
The numbers are probably wrong because you aren't seeking back to the beginning of the stringstream before trying to read it.

You don't need a stringstream at all. The code below extracts dates and verifies the format. Note that after each date is extracted, the stream is positioned just after the year. So it doesn't extract the newline if it's there.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>


int
main(int argc, char **argv)
{
    unsigned m, d, y;
    char delim1, delim2;
    while (std::cin >> d >> delim1 >> m >> delim2 >> y) {
	if (delim1 == '/' && delim2 == '/') {
	    std::cout << m << " / " << d << " / " << y << '\n';
	} else {
	    std::cout << "Badly formatted date: " << delim1 << delim2 << '\n'; 
	}
    }
    return 0;
}

Topic archived. No new replies allowed.