Segmentation Fault

I am getting a Segmentation Fault error.

The code works fine in my "load arrays function" after I've loaded the arrays. I pasted it at the very bottom inside that function. After it finished with that function, it calls my next one, outputData. That one has all the same variables passed to it, but the chunk of code that works in loadArrays will not work in the next function outputData. While testing it, I commented out large portions to get down to what was causing it.

This line
cout <<"line61: " <<mPtr[j].transactionType::GetDay() <<endl;

highlights where it is giving me the Seg. Fault.

If anyone could help, I'd appreciate it.

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
// Author:                                                 -->
// CLID:           
// Course/Section:
// Assignment:     proj3
// Date Assigned:  ?
// Date/Time Due:  
//
// Description: 
//
// 
//                

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <stdlib.h>  //needed for exit(1) to work
#include "transaction.h"
#include "merchandise.h"
#include "service.h"

using namespace std;

void loadArrays(merchandiseType* mPtr, serviceType* sPtr, int&, int&);
void outputData(merchandiseType* mPtr, serviceType* sPtr, int&, int&);

int main()
{ 

   merchandiseType *mPtr = NULL;    //merch. pointer
   serviceType *sPtr = NULL;        //service pointer
  
   int countM = 0, countS = 0;        //for size of the dynamic arrays
  
   cout << fixed << setprecision(2) << showpoint;
   //cout.unsetf(ios::fixed); //remove decimal formatting
  
   //inFile.open(strVar.c_str()); //to use a user's file name.

   loadArrays(mPtr, sPtr, countM, countS); 
   outputData(mPtr, sPtr, countM, countS);/////////////////left off here
  
   return 0;
}

void outputData(merchandiseType* mPtr, serviceType* sPtr,int &countM,int &countS)
{
   string monthYear = ""; //re-pull monthyear (only var not passed)
   ifstream inFile;
   inFile.open("transaction.data");
   getline(inFile, monthYear); 
   inFile.close();
   
   cout << endl <<monthYear <<endl;
   cout << "Trans Type  || (D)ay || (A)mount || (C)ust. # || (I)tem or (E)mp # || (Q)uantity or (S)ervice Desc.\n\n"; //REDO????????????
   for(int i=1; i<=31; i++)
   {
	   //cout << " line58: countM=" <<countM; //countM=3
      for(int j=0; j<countM; j++)
      {   
      	cout <<"line61: " <<mPtr[j].transactionType::GetDay() <<endl;
         /*if(mPtr[j].transactionType::GetDay() == i){
            cout <<"M " <<"(D): " <<mPtr[j].transactionType::GetDay() <<"(A): " <<mPtr[j].transactionType::GetAmount()
               <<"(C): " <<mPtr[j].transactionType::GetCust() <<"(I): " <<mPtr[j].GetItemNumber() <<"(Q): "
               <<mPtr[j].GetQuantity() <<endl;}*/
      }
      //cout << " line66: countS=" <<countS;  //countS=3
      /*for(int k=0; k<countS; k++)
      {  //**********************SEGMENTATION FAULT in if statement below***********************
         if(sPtr[k].transactionType::GetDay() == i){
            cout <<"S " <<"(D): " <<sPtr[k].transactionType::GetDay() <<"(A): " <<sPtr[k].transactionType::GetAmount()
               <<"(C): " <<sPtr[k].transactionType::GetCust() <<"(E): " <<sPtr[k].GetEmpNumber() <<"(S): "
               <<sPtr[k].GetDescription() <<endl;}
      }*/
   }
}

void loadArrays(merchandiseType* mPtr, serviceType* sPtr, int &countM, int &countS)
{
   ifstream inFile;
   
   int sizeM = 5, sizeS = 5;
   string monthYear = ""; //stores month and year at top of inFile
   char transChar; //draws a char from the input file before it goes into array
   
   int theDay = 0;         // these three apply to all
   float theAmount= 0;
   string strCustNum = "";
   
   string strItemNum = ""; // these two for merch only
   int theQuantity = 0;
   
   int theEmpNumber  = 0; // these two for service only
   string strDesc = "";
   
   //merchandiseType *mPtr = new merchandiseType[sizeM];?????????????????
   mPtr = new merchandiseType[sizeM];
   sPtr = new serviceType[sizeS];
   
	inFile.open("transaction.data");
   if(inFile.fail())
   {
     cout << "Error reading file -- program terminating.\n";
     exit(1);
   }
   getline(inFile, monthYear);  
   
   inFile >> transChar;
   while (inFile)
   {
      inFile >> theDay;       // these apply to both, so safe to pull
      inFile >> theAmount;
      inFile >> strCustNum;
      
      if (transChar == 'M'){
         inFile >> strItemNum;
         inFile >> theQuantity; // now all variables for the line have been pulled
         cout << "line119: M " <<theDay <<" " <<theAmount <<" " <<strCustNum <<" " <<strItemNum <<" " <<theQuantity <<endl;
         mPtr[countM].Initialize(theDay, theAmount, strCustNum, strItemNum, theQuantity);
         
         //cout <<"line122: " <<mPtr[countM].transactionType::GetDay() <<endl;
         
         countM++;
         if (countM == sizeM)    //if true: copy, change size, clear old, refill
         {
            merchandiseType *tempM = new merchandiseType[sizeM + 5]; //??????????????????can keep redecaling a new one over and over???
            for (int i=0; i<sizeM; i++)
               tempM[i] = mPtr[i]; // deep copy from mPtr to temp
            sizeM = sizeM + 5;
            delete []mPtr; //UNflag, mark as available and clear
            mPtr = tempM; // shallow copy of array referenced by temp to mPtr
         }
         
      }
      else if (transChar == 'S'){
      /*SERVICE read and process goes here*/  //*****Caveat: getline(inFile,dummy)
         inFile >> theEmpNumber;
         getline(inFile, strDesc); // now it pulls the end of the line 
         /* now all variables for the line have been pulled */
         
         cout << "line141 S " <<theDay <<" " <<theAmount <<" " <<strCustNum <<" " <<theEmpNumber <<" " <<strDesc <<endl;
         sPtr[countS].Initialize(theDay, theAmount, strCustNum, theEmpNumber, strDesc);
         
         countS++;
         if (countS == sizeS)    //if true: copy, change size, clear old, refill
         {
            serviceType *tempS = new serviceType[sizeS + 5];
            for (int i=0; i<sizeS; i++)
               tempS[i] = sPtr[i]; // deep copy from mPtr to temp
            sizeS = sizeS + 5;
            delete []sPtr; //UNflag, mark as available and clear
            sPtr = tempS; // shallow copy of array referenced by temp to mPtr
         }  
      
      }
      inFile >> transChar;
      cout << "countM: " <<countM <<"countS: " <<countS;
   } // end while (inFile)
   
   inFile.close();
   inFile.clear();
   
   //PASTED FROM OUTPUT FUNC
   cout <<"LINE164********";
   for(int i=1; i<=31; i++)
   {
	   //cout << " line58: countM=" <<countM; //countM=3
      for(int j=0; j<countM; j++)
      {   
      	//cout <<"line122: " <<mPtr[j].transactionType::GetDay() <<endl;
         if(mPtr[j].transactionType::GetDay() == i){
            cout <<"M " <<"(D): " <<mPtr[j].transactionType::GetDay() <<"(A): " <<mPtr[j].transactionType::GetAmount()
               <<"(C): " <<mPtr[j].transactionType::GetCust() <<"(I): " <<mPtr[j].GetItemNumber() <<"(Q): "
               <<mPtr[j].GetQuantity() <<endl;}
      }
      //cout << " line66: countS=" <<countS;  //countS=3
      for(int k=0; k<countS; k++)
      {  
         if(sPtr[k].transactionType::GetDay() == i){
            cout <<"S " <<"(D): " <<sPtr[k].transactionType::GetDay() <<"(A): " <<sPtr[k].transactionType::GetAmount()
               <<"(C): " <<sPtr[k].transactionType::GetCust() <<"(E): " <<sPtr[k].GetEmpNumber() <<"(S): "
               <<sPtr[k].GetDescription() <<endl;}
      }
   }
   
   
   
}
Last edited on
You don't need to comment out stuff - just use a debugger. Set a breakpoint at the area before where you think the error occurs, and then just step forward until the seg fault occurs. Then just check what exactly caused the error (mostly it's dereferencing unitialized pointers), and next time look at where that value is set.

Aside from that, stuff that I noticed:
1) include cstdio, not stdio.h.
2) mPtr[j].transactionType::GetDay()
I hope that transactionType is a member of merchandiseType and not a subclass. Because in that case, you are doing something very very evil here.
Last edited on
the debugger tells me roughly where the line number is, but it isn't specific enough. I don't know what you mean by setting a breakpoint. I've never done that before.

Below are the header files and implementation files for each. Merchandise class is derived from Transactionm, yes...it's not a member. I use Initialize to set the values. I must have done that wrong. I know I changed how I called Trans. Initialize from the Merch. func Initialize, and that could be what is not initializing all my variables. I got desperate and started trying anything that would get it to compile. I'm confused obviously on how to call things. I thought I had it right the first time, but it wouldn't compile that way, so I change it despite that I thought it should. I'm lost now.

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
#ifndef TRANSACTION_H
#define TRANSACTION_H
#include <string>

using namespace std;

class transactionType
{
   public:
      int GetDay() const;
      float GetAmount() const;
      string GetCust() const;
      
      void Initialize(int, float, string);
      
      transactionType(); //constructor default
      transactionType(int, float, string); //param'ized constructor
   
   private:
      int day;
      float amount;
      string custNumber;
};

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef MERCHANDISE_H
#define MERCHANDISE_H
#include <string>
using namespace std;


class merchandiseType: public transactionType
{
   public:
      string GetItemNumber() const;
      int GetQuantity() const;
      
      void Initialize(int, float, string, string, int);
      
      merchandiseType();                            //constructor default
      merchandiseType(int, float, string, string, int); //constr. param'ized
   private:
      string itemNumber;
      int quantity;
};

#endif 


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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <stdlib.h>  //needed for exit(1) to work
#include "transaction.h"

transactionType::transactionType()
{
   day = 0;
   amount = 0;
   custNumber = "";
}

transactionType::transactionType(int theDay, float theAmount, string strCustNum)
{
   day = theDay;
   amount = theAmount;
   custNumber = strCustNum;
}

int transactionType::GetDay() const
{
   return day;
}

float transactionType::GetAmount() const
{
   return amount;
}

string transactionType::GetCust() const
{
   return custNumber;
}

void transactionType::Initialize(int theDay, float theAmount, string strCustNum)
{
   day = theDay;
   amount = theAmount;
   custNumber = strCustNum;
}


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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <stdlib.h>  //needed for exit(1) to work
#include "transaction.h"
#include "merchandise.h"

merchandiseType::merchandiseType():transactionType() /*?????????????init's the first 3?*/
{
   itemNumber = "";
   quantity = 0;
}

merchandiseType::merchandiseType(int theDay, float theAmount, string strCustNum, string strItemNum, int theQuantity):transactionType(theDay,theAmount,strCustNum)
{
   itemNumber = strItemNum;
   quantity = theQuantity;
}

string merchandiseType::GetItemNumber() const
{
   return itemNumber;
}

int merchandiseType::GetQuantity() const
{
   return quantity;
}

void merchandiseType::Initialize(int theDay, float theAmount, string strCustNum, string strItemNum, int theQuantity)
{
   itemNumber = strItemNum;
   quantity = theQuantity;
   
   /*merchandiseType.*/transactionType::Initialize(theDay, theAmount, strCustNum);/*?????????????*/
}
I found the error, which is that I was wrong in thinking pointers are passed by reference by default. So, I changed the prototype and the definition to what it should be to accomplish that. Here's the format for a parameter for a pointer by reference:

theType* &varPtr

example:

void func (int* &myPtr)

Just in case anyone else ever needs to know. :)
Topic archived. No new replies allowed.