segmentation fault/ basic array, menu driven program

I'm pretty new to c++, and am trying to make a menu driven program. When i run the fourth option, it gives me a segmentation fault. Also, a few of the other functions do not work ( pretty much 4-10). I'm not asking for answers, but any help, or direction would be greatly appreciated. It's based off of high/ low temperatures listed in a file.



// Directives
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

// Global Constants

const char BELL = '\007'; // The bell to alert user
const int MAX_NAME = 30; // Longest file name to accept
const int MAX_DAY = 31; // maximum number of days the file will give max$
const int QUIT_CHOICE = 11; // gives the user the ability to quit the p$

// Function Prototypes
void Instructions();
void Do_Choice (int choice, int low_temp[], int high_temp[], int&total_days);
void Ask_File(int low_temp[], int high_temp[], int&total_days);
void Print_Ascending_By_Day(int low_temp[], int high_temp[], int total_days);
void Ascending_Temp_High(int low_temp[], int total_days, int high_temp[]);
void Ascending_Temp_Low(int low_temp[], int total_days, int high_temp[]);
void Calc_Stats (int high_temp[], int total_days);
void Print_Graph_High(int high_temp[], int total_days);
void Relative_Temp(int high_temp[], int low_temp[], int total_days);
int Temp_Menu();int main()
{
int total_days; // total # of days in the file
int choice; // choice to question
int low_temp[MAX_DAY]; // arrary of low temperatures
int high_temp[MAX_DAY]; // arrary of high temperatures

do
{
choice = Temp_Menu();
Do_Choice (choice, low_temp, high_temp, total_days);
} while (choice < QUIT_CHOICE);
return 0;
}int Temp_Menu()
{
int day; // # temperature/ day (same thing)
ifstream data_in; // Object for accessing input from file
int choice;

do
{
cout << endl;
cout << "Menu " << endl;
cout << "1. Instructions " << endl;
cout << "2. Load a file of temperature data " << endl;
cout << "3. Display the high and low temps in ascending "
"order by day " << endl;
cout << "4. Display the high and low temperatures in ascending "
"order by low temperature " << endl;
cout << "5. Display the high and low temperatures in ascending "
"order by high temperature " << endl;
cout << "6.Display the high,low and mean (average) temperature "
"for the high temperatures " << endl;
cout << "7.Display the high, low and mean temperature for the low"
" temperatures " << endl;
cout << "8.Display the relative temperature range for each "
" day " << endl;
cout << "9. Display a sideways bar graph of the high temperatures "
" in order by day " << endl;
cout << "10. Display a sideways bar graph of the low temperatures "
"in order by day " << endl;
cout << "11. Quit " << endl;
cout << endl;
cout << " What is your choice (1- " << QUIT_CHOICE<< ")" ;
cin >> choice;
if (( choice < 1) || (choice > QUIT_CHOICE)) {
cout << BELL << BELL;
cout << "Press Enter to Quit Choice ";
}

}while (( choice < 1) || (choice > QUIT_CHOICE));

return (choice);
That's the basic variable and constants, I'm not going to post my entire program, but this section is the one I'm having the segmentation fault with, and the one giving me quite a bit of trouble. void Ascending_Temp_Low(int low_temp[], int total_days, int high_temp[])
{
bool in_order; // Boolian character for listing index in order
in_order = true;
int num_day; // number of spaces in index of array
do
{
for(num_day = 0; num_day < (total_days-1); num_day++)
{
if(low_temp[num_day]< low_temp[num_day+1])
Swap(low_temp[num_day] , low_temp[num_day+1]);
Swap(high_temp[num_day] , high_temp[num_day+1]);
in_order = false;
}
} while (! in_order);
cout << setw(5) << "High Temp";
cout << setw(5) << "Low Temp";
for (num_day = 0; num_day < total_days; num_day++)
{
cout << setw(5) << high_temp[num_day];
cout << setw(5) << low_temp[num_day];
}
return;
}
First, please please please use code tags. If you see the <> icon on the left of your post, that will let you stick this in a format that preserves tabs, spaces, etc.

Second, Right before Ascending_Temp_Low, you are missing a }.

Third, when you select 4 in your menu, Temp_Menu returns 4. That causes main() to call Do_Choice(4,...);. We don't know what is inside Do_Choice, but I can almost guarentee you that the problem is in that function.

A seg fault will often occur when you go out of bounds of an array. Example:
1
2
3
int MyArray[3];
MyArray[2] = 0; // OK
MyArray[3] = 0; // Seg fault because this piece of memory is not allocated to this array. 
Ok, my menu choice 3 works though, and my Instructions function, which is why I'm pretty confused about it. Here is my Do_Choice Function, hopefully i insert it correctly this time, sorry about my previous mistake:

[code]void Do_Choice (int choice, int low_temp[], int high_temp[], int & total_days)
{
switch(choice)
{
case 1:
Instructions();
break;
case 2:
Ask_File( low_temp, high_temp, total_days);
break;
case 3:
Print_Ascending_By_Day( low_temp, high_temp, total_days);
break;
case 4:
Ascending_Temp_Low(low_temp, total_days, high_temp);
break;
case 5:
Ascending_Temp_High(low_temp, total_days, high_temp);
break;
case 6:
Calc_Stats ( high_temp, total_days);
break;
case 7:
Calc_Stats ( low_temp,total_days);
break;
case 8:
Relative_Temp( high_temp,low_temp, total_days);
break;
case 9:
Print_Graph_High( high_temp, total_days);
break;
case 10:
Print_Graph_High( low_temp, total_days);
break;
case 11:
default:
break;
}
return;
}
/code]
Close, as you wrote [ code] correctly, but you forgot the [ in [/code].

Regardless, we now know that:
Print_Ascending_By_Day(low_temp,high_temp,total_days);
is not breaking anything but,
Ascending_Temp_Low(low_temp,total_days,high_temp);
is having a problem. Let's see the definition of that second function
What do you mean by definition of the function?

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
void Ascending_Temp_Low(int low_temp[], int total_days, int high_temp[]);



void Ascending_Temp_Low(int low_temp[], int total_days, int high_temp[])
{
    bool in_order;      // Boolian character for listing index in order   
    in_order = true;    
    int num_day;        // number of spaces in index of array
    do
    {
        for(num_day = 0; num_day < (total_days-1); num_day++)
        {
            if(low_temp[num_day]< low_temp[num_day+1])
            Swap(low_temp[num_day] , low_temp[num_day+1]);
            Swap(high_temp[num_day] , high_temp[num_day+1]);
            in_order = false;
        }
    } while (! in_order);
    cout << setw(5) << "High Temp";
    cout << setw(5) << "Low Temp";
    for (num_day = 0; num_day < total_days; num_day++)
    {
        cout << setw(5) << high_temp[num_day];
        cout << setw(5) << low_temp[num_day];
    }
    return;
}

[in
Line 1 is the declaration,

Lines 5-28 are the defintion.

Found your problem... total_days is never initialized. That means that it is some random number that is larger than MAX_DAY. This means that when you chose low_temp[num_day] where num_day >= MAX_DAY, you'll have a seg fault.

Solution: in your int main() function change:
int total_days; // total # of days in the file
to
int total_days=MAX_DAY; // total # of days in the file
Last edited on
Do we know the value of total_days being passed into Ascending_Temp_Low?

I see where it's declared, but I don't see where it's set. If that's an uninitialized variable that would cause a segmentation fault because that would be an invalid index into your array.
I really appreciate it guys, thanks a lot! Hopefully it runs a little smoother now.
Now, instead of a segreation error, it displays nothing at all, so do I need to change all of the parameters for the functions to say total_days = MAX_DAY? I'm assuming its a problem with the Do_Choice function
Ah ha,

In this case, you are entering an infinite loop in Ascending_Temp_Low(). If we walk through it, we set in_order = true in line 8. Then we enter a do-while loop where in_order is set to false in the for loop. Once we exit the for loop, we have in_order = false and it will never be set to true again.

Solution:
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
void Ascending_Temp_Low(int low_temp[], int total_days, int high_temp[])
{
    bool in_order; 
    int num_day;   
    do
    {
        int in_order = true; // Set this to TRUE inside of the loop.
        for(num_day = 0; num_day < (total_days-1); num_day++)
        {
            if(low_temp[num_day]< low_temp[num_day+1])
            { // Note you were missing {s around the actions to be done in the if statment
                std::swap(low_temp[num_day] , low_temp[num_day+1]);
                std::swap(high_temp[num_day] , high_temp[num_day+1]);
                in_order = false;
            } // You were missing this too
        }
    } while (! in_order);
    cout << setw(5) << "High Temp";
    cout << setw(5) << "Low Temp";
    for (num_day = 0; num_day < total_days; num_day++)
    {
        cout << setw(5) << high_temp[num_day];
        cout << setw(5) << low_temp[num_day];
    }
    return;
}


Edit: I fixed your syntax mistakes here, but I tried it out and it's still broken (infinite loop). This means that the problem is now in the sorting algorithm.
Last edited on
Topic archived. No new replies allowed.