Why does my program crash when compiled

Implement a class named Country that stores information about a country, such as its name, its population and its area. The class should have the following private member variables:

name - a string that holds the name of the country
population - a long int that is the number of people in the country
area - a double that is the area of the country in some units
You may add additional member variables such as the capital of the country, if you wish.

The class should have

1. at least one constructor that initializes all the private member variables.

2. mutator functions to assign values to the private member variables and accessor functions that return the values of each of the member variables.

3. when assigning the population and the area, do not allow negative values. If the user tries to assign a negative value, set the value to zero and write out an informative message to standard output.

Use the class in a source code that creates an array of Country objects. The code should read in the values from an external file, myCountrydata.txt, and user the mutator functions to assign the values to the member variables. The code will then pass the array of objects and its size to a function calcCountry() that

1. calculates which country has the largest area. It prints the country's name and its area using the accessor functions to standard output.

2. calculates which country has the largest area. It prints the country's name and its population using the accessor functions to standard output.

3. calculates which country has the largest population density, people per square unit, and prints that information to standard output.

THE PROGRAM CRASHES! Please help...

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

class Country
{
private:
string name;
long population;
double area;

public:
Country ();
string setName (string);
void setPopulation (long);
void setArea (double);
string getName ();
int getPopulation ();
double getArea ();
};

void calcCountry (Country [], int);

Country::Country ()
{
population=0;
area=0;
name="NULL";
}

//=============================================
string Country::setName (string cname)
{
name=cname;
}
//============================================
void Country::setPopulation(long pop)
{
if (pop >= 0)
population=pop;
else
{ population=0;
cout << "Invalid population. Using a default value of 0";
}
}
//==============================================
void Country::setArea(double a)
{
if (a >= 0.0)
area=a;
else
{ area=0;
cout << "Invalid area. Using a default value of 0";
}
}
//==============================================
string Country::getName ()
{
return name;
}
//================================================
int Country::getPopulation()
{
return population;
}
//==================================================
double Country::getArea()
{
return area;
}
//=====================================================

void calcCountry (Country country[], int k)
{
int maxpos = 0;

for (int i=0; i<k; i++){
if (country[i].getArea() > maxpos){
maxpos=i;
}
}
cout << "The country " << country[maxpos].getName() << "has the biggest area of " <<country[maxpos].getArea() << endl;;

for (int i=0; i<k; i++){
if (country[i].getPopulation() > maxpos){
maxpos=i;
}
}
cout << "The country " << country[maxpos].getName() << "has the biggest population of " <<country[maxpos].getPopulation() << endl;;


for (int i=0; i<k; i++){
if ((country[i].getPopulation()/country[i].getArea()) > maxpos){
maxpos=i;
}
}
cout << "The country " << country[maxpos].getName() << "has the biggest density of " << (country[maxpos].getPopulation()/country[maxpos].getArea()) << endl;
}

//==============================================================================================================================================================
const int n=6;

int main()
{
ifstream infile;
infile.open("myCountrydata.txt");

string cname;
long pop;
double a;

Country country [n];

if (!infile) {
cout << "File could not open for reading." << endl;
exit(1);
}

int i=0;

while (i < n && !infile.eof()){
infile >> cname >> pop >> a;
country[i].setName(cname);
country[i].setPopulation(pop);
country[i].setArea(a);
i++;
}

calcCountry(country, n);

infile.close();
return 0;
}
I see two problems:

1. a potential division by zero:
1
2
3
4
5
6
7
for (int i=0; i<k; i++){
if ((country[i].getPopulation()/country[i].getArea()) > maxpos){ // crash if country[i].getArea() -> 0
maxpos=i;
}
}
cout << "The country " << country[maxpos].getName() << "has the biggest density of " << (country[maxpos].getPopulation()/country[maxpos].getArea()) << endl; // crash if country[maxpos].getArea() -> 0
}


2. You read one too far:
1
2
3
4
5
6
7
while (i < n && !infile.eof()){
infile >> cname >> pop >> a; // What happens if eof occurs here?
country[i].setName(cname);
country[i].setPopulation(pop);
country[i].setArea(a);
i++;
}
better so:
1
2
3
4
5
6
while (i < n && (infile >> cname >> pop >> a)){
country[i].setName(cname);
country[i].setPopulation(pop);
country[i].setArea(a);
i++;
}


if you read less than 6 elements from the file you will have a zero area due to:

calcCountry(country, n); // n should be i
Last edited on
Read warnings: warning: no return statement in function returning non-void
1
2
3
4
string Country::setName (string cname)
{
    name=cname;
}
You promised that you will return string. You did not. Program still behaves as if you did and crashes because you did not fulfill your promise.
1
2
3
4
5
for (int i=0; i<k; i++){
if (country[i].getArea() > maxpos){
maxpos=i; 
} // this will fail very quickly, because you're comparing country's area to index which is less than 6 - similar problems in the rest of the function
}


try
1
2
3
4
5
for (int i=0; i<k; i++){
if (country[i].getArea() > country[maxpos].getArea()){
maxpos=i; 
} // comparing areas to areas
}
MiiNiPaa, thank you! You solved my problem. Now it doesn't crash but it just gives me the area and population of the last line/country in the file.
Tipaye, you sold my other problem. Thank you as well!
Topic archived. No new replies allowed.