Loop giving a segmentation fault

Hey guys, I've been on here for a while now but just now i registered because I don't know how to fix this after reading numerous posts.Btw you guys helped me a ton this semester.
The code im writing is for a class project. It takes in user input planet name, mass, radius. Then it calculates area, density and gravity(almost). It uses vectors to add, delete, search for by name and sorts by name and also displays all data.

This is the part that gives me an error:

I'm pretty sure its with the logic of the loop. What it does is takes in an input of a user and searches a vector for that input and it displays that information for the user. After that however it gives a segmentation error and quits the program alltogather instead of going back to the menu.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
string  Plist::FindPlanet()
	{	
		string X;
		bool test=false;
		cout << "Enter name of planet to look for: ";
		while(!test)
		{
		cin>>X;
		cin.ignore(500,'\n');
		for(int i=0; i<P.size();++i)
			if(X==P[i].getname())  P[i].Display();
		else test = true;     
		break;
		}
		
	}
		


This is the rest of the code just incase(All of it works except gravity returns inf but that ill fix by passing by refferance.)
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
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <iomanip>
#include "planet.h"
using namespace std;
double G=6.67e-11,Mass=0.0, m=0.0, r=0.0, Gravity=0.0; 

int menu()
{  
int choice=0;
do{
   cout<<"1.Add Planet\n";
   cout<<"2.Display planet names \n";
   cout<<"3.Display planets and data\n";
   cout<<"4.Sort planets by name\n";
   cout<<"5.Search for a planet by name\n";
   cout<<"6.Destroy Planet\n";
   cout<<"7.Quit\n";
   choice=returnchoice("Enter # of choice:");
   if (choice  >7 || choice < 1 ){
       cout<< " Choice must be 1-7. " <<endl;
       }
}
while(choice<1 || choice>7);
   return choice;
}


class Planet
{
	private:
		double radius;
		double mass;
		std::string name;
		
	public:
		std::string& getname();
		void Input();
		double Area();
		double Volume();
		double Density();
		double Gravity();
		double getradius();
		double getmass();
		void Display();
		void DisplayNames();
		std::string setname()
		{
			cout<<"Enter name of planet: ";
			cin.ignore(500,'\n');
			getline (cin, name);
		}
		bool setradius(double radius)
		{
			bool rv=false;
			if (r>0.0){
				rv=true;
				radius=r;
				}
			return rv;
		}
		bool setmass(double mass)
		{
			bool mv=false;
			if (m>0.0){
				mv=true;
				mass=m;
				}
			return mv;
		}
		
		Planet();
		Planet(double radius, double mass);
};
	double Planet::getradius()
		{return radius;}
	double Planet::getmass()
		{return mass;}
	string& Planet::getname()
		{return name;}
	void Planet::Input()
		{setname();
		radius=readdouble("Please enter radius in meters: ");
		mass=readdouble("Please enter mass in kilograms: ");}
	double Planet::Area()
		{return 4.0*M_PI*pow(radius,2.0);}
	double Planet::Volume()
		{return(4.0/3.0)*M_PI*pow(radius,3.0);}
	double Planet::Density()
		{return getmass()/Volume();}
	double Planet::Gravity()
		{return (G*(getmass()))/(pow(r,2.0));}
	void Planet::Display()
		{
		cout<<"Name:"<<name<<endl;
		cout<<"Mass: "<<getmass()<<endl;
		cout<<"Radius is: "<<getradius()<<endl;
		cout<<"Area is: "<<Area()<<endl;
		cout<<"Density is: "<<Density()<<endl;
		cout<<"Gravity is: "<<Gravity()<<endl;}	
	void Planet::DisplayNames()
		{cout<<"Name: "<<name<<endl;}
	Planet::Planet()
		{setradius( radius);}
	Planet::Planet(double radius, double mass)
		{setradius(r); setmass(m);}
class Plist
{
	public:
	vector <Planet> P;
	bool Add();
	bool Delete(int idx);
	void Dumplist();
	void DumpNames();
	void Show(int idx);
	void Sort();
	std::string FindPlanet();
	
	private:
	bool Pass();
};
bool Plist::Add()
{
	bool rv=false;
	if(P.size()<P.max_size()){
	Planet newP;
	newP.Input();
	P.push_back(newP);
	rv=true;}
	return rv;}

bool Plist::Delete(int idx)
{ 
	bool rv=false;
	if (idx>=0 && idx<P.size()){
		rv=true;
		P[P.size()-1]=P[idx];
		P.pop_back();}
		return rv;}
void Plist::Show(int idx)
{
	if (idx>=0 && idx<P.size())
		P[idx].Display();
}	
void Plist::Dumplist()
{
	for (int i=0;i<P.size();i++)
		P[i].Display();
}
void Plist::DumpNames()
{
	for (int i=0;i<P.size();i++)
		P[i].DisplayNames();
}
void Plist::Sort()
{
	while(Pass()==false);
}
bool Plist::Pass()
{
	bool rv=true;
	long tmp=P.size()-1;
	for(long i=0;i<tmp;i++){
		if(P[i].getname()>P[i+1].getname()){
			rv=false;
			Planet tmp=P[i];
			P[i]=P[i+1];
			P[i+1]=tmp;
		}
	}
	return rv;
}
string  Plist::FindPlanet()
	{	
		string X;
		bool test=false;
		cout << "Enter name of planet to look for: ";
		while(!test)
		{
		cin>>X;
		cin.ignore(500,'\n');
		for(int i=0; i<P.size();++i)
			if(X==P[i].getname())  P[i].Display();
		else test = true;     
		break;
		}
		
	}
		






int main()
{
Planet P;
Plist PL;
int idx=0;

	int choice;

do{
	choice=menu();
	switch (choice){
	case 1:
		PL.Add();	
		break;	
	case 2:
		PL.DumpNames();		
		break;	
	case 3: 
		PL.Sort();
		PL.Dumplist();
		break;
	case 4: 
		PL.Sort();
		break;
	case 5: 
		PL.FindPlanet();	
	break;
	
	
	case 6: 
		PL.Delete(idx);	
		break;

	default: cout<<"Goodbye!!!"<<endl;
			break;
		
	}
	
	}while(choice !=6);
return 0;

}


Thank you for your input in advance.
Does returning a string, or changing the return value into void help?

Since you do not originally return anything and judging from what the code does, it doesn't seem like you planned on returning a string.
As HoneyBoy notes, not returning something when you say you're going to return something is problematic.

The temporary the function (doesn't) return is going to be deconstructed, which means the string class is going to be interpreting some memory as a string object when it's not. That could easily cause your segmentation fault.

If you pay attention to your compiler warnings, this is easily avoided.
Ah thank you very much. This is what it looks like and also void at the decleration and I added an else statement if no such input is found. and the inf for gravity was fixed by changing r to radius in the calculation function. Is it ok to use break like that to get out of the loop?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Plist::FindPlanet()
	{	
		string X;
		bool test=false;
		cout << "Enter name of planet to look for: ";
		while(!test)
		{
		cin>>X;
		cin.ignore(500,'\n');
		for(int i=0; i<P.size();++i)
			if(X==P[i].getname())  
				P[i].Display();
			else {cout<<"No such planet found.\n";}
				break;
				}
		
	}
Last edited on
Erm, there's no reason for the loop to be there. Why don't you just remove the loop and control variable (and fix that horrid indentation.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Plist::FindPlanet()
{
    string planetName ;
    cout <<  "Enter name of planet to look for: " ;
    getline(cin, planetName) ;  // no ignore necessary

    unsigned index = 0 ;
    while ( index < P.size() &&  planetName != P[index].getname() )
        ++index ;

    if ( index < P.size() )
        P[index].Display() ;
    else
        cout << planetName << " not found.\n" ;
} 
Last edited on
Topic archived. No new replies allowed.