Program crashes right after compiling

can you guys take a look at my code? The program compiles, but crashes immediately as I open it. Any ideas?



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
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;

class payroll {
ifstream fin;
public: string lastname; 
char ms, paystatus;
int employeeid, i;
float taxrate;
double hoursworked, overtimehours, regularhours, hourlyrate, regularpay, minnp, maxnp, taxamount, netpay, grosspay, overtimepay, yearlysalary;
virtual double findgrosspay();
double findnetpay(), maxnet(double, int), minnet(double, int);
void settingthevariables(char[], int, char, char, double, double, double, double, double, double);
void sortdata(char[],double[],double[],double[]);
void printheaders();
void printdata();
void findtaxamount();
void printminmax(double, double);
payroll();
~payroll();
};

class hourly : public payroll {
public: double findgrosspay() { 
        if (hoursworked > 40 ) {
           overtimehours = hoursworked - 40;
           regularpay = 40 * hourlyrate;
           overtimepay = 1.5* hourlyrate * overtimehours;
           grosspay = overtimepay + regularpay  ; }
        else {
            grosspay = hoursworked * hourlyrate;
            regularpay = grosspay; }
            return grosspay; }; };

class salaried : public payroll {
public: double findgrosspay() { 
        regularpay = yearlysalary/52; 
        overtimehours = hoursworked - 40; 
        grosspay = regularpay;
        if (hoursworked > 0) {
        overtimehours = hoursworked - 40;
           overtimepay = 1.5* overtimehours * (regularpay/40);
           grosspay = regularpay + overtimepay;
return grosspay;
        }// If
};//findgrosspay
};

payroll::payroll() {
fin.open("2142011.in"); }
payroll::~payroll() {
fin.close();  }




void payroll::settingthevariables(char alastname[], int aemployeeid, char ams, 
char apaystatus, double ahoursworked, double ahourlyrate, double ayearlysalary, double ataxamount, double anetpay, double aovertimepay) {
     lastname = alastname;
     employeeid = aemployeeid;
     ms = ams;
     paystatus = apaystatus;
     hoursworked = ahoursworked;
     hourlyrate = ahourlyrate;
     yearlysalary=ayearlysalary;
     taxamount=ataxamount;
     netpay=anetpay;
     overtimepay= aovertimepay;
}
   
void payroll::findtaxamount() {
     taxrate = .30;
     taxamount = grosspay * taxrate;
}// findtaxamount

double payroll::findgrosspay() {
     overtimehours = 0;
     regularpay = 0;
     overtimepay = 0;
     grosspay = 0;
     if (hoursworked > 40 ) {
        overtimehours = hoursworked - 40;
        regularpay = hoursworked * hourlyrate;
        overtimepay = 1.5* overtimehours * hourlyrate;
        grosspay = regularpay + overtimepay; }
     else
        grosspay = hoursworked * hourlyrate;
        regularpay = grosspay;
return grosspay;
}

double payroll::findnetpay()  {
     netpay = grosspay - taxamount;
return netpay;
}

double payroll::minnet(double minnp, int i) {
     if (i == 0) {minnp = 10000000;}
     if (netpay < minnp) {minnp = netpay;}
return minnp;
} 

double payroll::maxnet(double maxnp, int i) {
     if (i == 0) {maxnp = 0;}
     if (netpay > maxnp) {maxnp = netpay;}
return maxnp;
} 


void payroll::sortdata( char lastname[] ,double overtimepay[],double taxamount[],  double netpay[] ) {
    int i,j,n;
  
    char *alastname[n]; 
    double *aovertimepay[n]; 
    double *ataxamount[n];
    double *anetpay[n];
    double *temp, *tempb, *tempc; 
    char *tempa; 
    int sorted = 0; 

      for( i = 0; i < n; i++ ){
         alastname[i] = lastname + i; 
         aovertimepay[i] = overtimepay + i;
         ataxamount[i] = taxamount +i;
         anetpay[i] = netpay + i; } //for
    
 while (!sorted){
         sorted = 1;
   
   for( j = 0; j < n -1; j++ ){  
      if ( *anetpay[j] > *anetpay[j+1] ){ 

         temp = anetpay[j];
         anetpay[j] = anetpay[j+1];
         anetpay[j+1] = temp;
         
         tempa = alastname[j];
         alastname[j] = alastname[j+1];
         alastname[j+1] = tempa;  
         
         tempb = aovertimepay[j];
         aovertimepay[j] = aovertimepay[j+1];
         aovertimepay[j+1] = tempb; 
         
         tempc = ataxamount[j];
         ataxamount[j] = ataxamount[j+1];
         ataxamount[j+1] = tempc; sorted = 0;
          
              }//if
         }//for
 }//while
}//sort



void payroll::printheaders(){

    cout << "------------------------------------------------------------------------------" << endl;
    cout << "LAST NAME      OT PAY         TAX            NETPAY"   << endl;
    cout << "-------------------------------------------------------------------------------" << endl;}

void payroll::printdata()    {

     
 	    cout<<setw(15)<<left<<lastname;
        cout<<setprecision(2)<<setiosflags(ios::fixed | ios::showpoint);
        cout<<setw(15)<<overtimepay<<setw(15)<<taxamount<<setw(15)<<netpay<<endl; 
             
}//printdata

void payroll::printminmax(double minnp, double maxnp) {
     cout<<endl<<"The Max. NETPAY is $"<<maxnp<<endl;
     cout<<"The Min. NETPAY is $"<<minnp<<endl;
}

int main() {
    payroll *employee[6], *report;
    char alastname[14],lastname[14], ams, apaystatus;
    int aemployeeid,n, i=0;

    double ahoursworked, ayearlysalary, ahourlyrate, minnp, maxnp, ataxamount,  anetpay, aovertimepay, taxamount[10000000],  netpay[100000000], overtimepay[100000000];

    report->printheaders();
    
    ifstream fin;
    fin.open("2142011.in");

    while (fin>>alastname>>aemployeeid>>ams>>apaystatus>>ahoursworked>>ahourlyrate>>ayearlysalary) {
           if (apaystatus == 's') {
           
              employee[i] = new salaried();
              employee[i]->settingthevariables(alastname, aemployeeid, ams, apaystatus, ahoursworked, ahourlyrate, ayearlysalary, ataxamount,  anetpay, aovertimepay);
              employee[i]->findgrosspay(); }
           if (apaystatus == 'h') {
              employee[i] = new hourly();
              employee[i]->settingthevariables(alastname, aemployeeid, ams, apaystatus, ahoursworked, ahourlyrate, ayearlysalary, ataxamount,  anetpay, aovertimepay);
              employee[i]->findgrosspay();}
           employee[i]->findtaxamount();
           employee[i]->findnetpay();
           
           
           employee[i]->sortdata(lastname,overtimepay,taxamount,netpay);
       
      
           minnp = employee[i]->minnet(minnp, i);
           maxnp = employee[i]->maxnet(maxnp, i);
           employee[i]->printdata();
           i++; 
     }
      

          report->printminmax(minnp, maxnp);
     
          fin.close(); 
          system ("pause");
} 
On line 185, report is a pointer to a payroll object, but you never actually create a payroll object for it to point to. You could make that function a static function, so it can be called without having to have an instance of the object, but since I suspect you do actually want to have a payroll object, you should just actually create one. employee is an array of pointers to payroll objects that don't exist until line 193, where you start making some. report will need something similar. Note that when you create an object with new, at some point it's good practice to delete it.

I note also that you create space on the stack for 210 million doubles. Is your stack big enough for that? I note that you only make 10 million taxamounts when you have 100 million netpay and 100 million overtimepay values. Are they all meant to be 100 million? Even if this compiles, there is a chance of it not working at runtime. With an eight byte double, this will take up over a gig and a half of RAM. I seem to recall that the default stack size on windows is on the order of 8MB? Maybe it was 16MB? I'm not sure, but a lot, LOT less than one and a half GB.

On line 115 116 117 118 you create variable length arrays on the stack. Strictly, this is forbidden in C++. Your compiler may allow you to get away with it; it really shouldn't, especially not without you being aware of it. What is not so great is that you're using 'n' as your variable size, and you never actually set 'n' to a value, so it will be whatever garbage value happens to be in memory occupied by 'n' at the time you run it. You've got some loops there using 'n' as well, so they will run an undefined number of times because you never set 'n'.

In your salaried class, there is a valid path through public: double findgrosspay() that will result in you not returning a double.
Last edited on
Thanks Moschops.

I have changed the double space to 10000 for tax,np,otpay. I set n=10 for lines 115-118 as I only have 5 data pts.

I am still very new at this , can you elaborate on #1 and #4? I thought payroll *employee[6], *report; was the payroll objects declaration? I tried replacing it with payroll employee, report; and I recieve no match operator errors.

Regarding #4, I thought return grosspay; would guarantee a returned double? Bc gross and reg pay are defined as doubles.
payroll* report; creates a pointer to an object of type payroll. The pointer is named report. A pointer object is usually the size of an integer, and it sits in memory waiting for you to give it a value. That value will be the address of what you want it to point to. A pointer is a complete, valid object that takes up memory. It is up to you to make it point to something.

payroll report; creates an object or type payroll, named report.

Do you see the difference? The first creates a pointer. It does not create what you want it to point to.

1
2
3
4
payroll* p_report; // create a pointer. Currently is not pointing at a payroll object
payroll report; // create an object of type payroll
p_report = &report; // give the pointer the value of address of the object named report.
     //  p_report now points at a valid payroll object; the one named report. 



payroll *employee[6] creates an array, This array is named employee. What is it an array of? An array of payroll* objects. What are payroll* objects? They are pointers. You have made an array of pointers to payroll objects, but you have not made the actual payroll objects.

Regarding #4; what happens in salaried::findgrosspay() if hoursworked equals zero or less than zero?
Last edited on
Still a little confused about the arrays- so youre saying I need to create the array to access the objects defs below? I thought findgrosspay, tax amount, etc... were functions I called in the main block.

1
2
3
4
5
6
7
8
9
payroll* p_report;
payroll report;
payroll p_settingthevariables;
payroll p_findgrosspay;
payroll p_findtaxamount ;          
payroll p_findnetpay ;          
payroll p_sortdata;    
payroll p_minnet;          
payroll p_maxnet; 
In my notation, 'p_' indicates a pointer. It's a useful habit I've fallen into over the years after trashing the stack one too many times with a poorly formed memset.

Anyway, that aside, what I'm saying is this: when you create a pointer, you still need to manually create the object for it to point to, and ensure that it does point to it.

Looking at your code, I don't see any need for you to create pointers to payroll objects. You can just create the payroll object. Then, instead of report->printheaders();, you can just use report.printheaders();

In this line, payroll *employee[6], *report;, why create pointers? Why not just create payroll objects, like this:

1
2
payroll employee[6];
payroll report;


This will create an array of payroll objects, named employee, and a payroll object called report, and you won't have to worry about pointers. Then, call their functions as normal:

report.printheaders(); employee[i].findgrosspay();

and so on.

This code you suggested:
1
2
3
4
5
6
7
8
9
payroll* p_report;
payroll report;
payroll p_settingthevariables;
payroll p_findgrosspay;
payroll p_findtaxamount ;          
payroll p_findnetpay ;          
payroll p_sortdata;    
payroll p_minnet;          
payroll p_maxnet;


will create one pointer, and seven eight payroll objects with funny names.


Last edited on
Topic archived. No new replies allowed.