2017-03-12 9 views
0

Ich versuche den Additionsoperator zu überladen, aber ich bekomme immer einen Segmentierungsfehler, obwohl ich das Argument nach Wert übergeben habe, nachdem der Speicher freigegeben wurde. Jeder hat eine Idee, was ich falsch machen könnte. Auch wenn ich das nach dem Fixieren des überladenen Zusatzes richtig laufen lasse, muss ich Vektoren verwenden, anstatt auf Arrays zu zeigen, von denen ich keine Ahnung habe, wie man sie deklariert, wie ich es für Arrays beschrieben habe.Segmentierungsfehler beim Überladen von Additionsoperator und dynamischen Vektoren

RowAray.h

#ifndef ROWARAY_H // if constant ROWARAY_H not defined do not execute 
#define ROWARAY_H // defines constant ROWARAY_H 
#include <new>  // Needed for bad_alloc exception 
#include <cstdlib> // Needed for the exit function 


template <class T> 
class RowAray{ 
    private: 
     int size; 
     T *rowData; 
     void memError(); // Handles memory allocation errors 
     void subError(); // Handles subscripts out of range 
    public: 
     RowAray(T); //used to construct row Array object 
     ~RowAray(){delete [] rowData;} //used to deallocate dynamically allocated memory from Row array 
     int getSize(){return size;} //inline accessor member function used to return length of Row array 
     void setData(int row, T value); 
     T getData(int i){return ((i >=0&& i < size)?rowData[i]:0);} // 
     T &operator[](const int &); 
}; 
template <class T> 
RowAray<T>::RowAray(T colSize){ 
    size =colSize>1?colSize:1; 
    // Allocate memory for the array. 
    try 
    { 
     rowData = new T [size]; 
    } 
    catch (bad_alloc) 
    { 
     memError(); 
    } 

    // Initialize the array. 
    for (int count = 0; count < size; count++){ 
     T value = rand()%90+10; 
     setData(count, value); 
    } 

} 

template <class T> 
void RowAray<T>::memError() 
{ 
    cout << "ERROR:Cannot allocate memory.\n"; 
    exit(EXIT_FAILURE); 
} 

template <class T> 
void RowAray<T>::subError() 
{ 
    cout << "ERROR: Subscript out of range.\n"; 
    exit(EXIT_FAILURE); 
} 

template <class T> 
T &RowAray<T>::operator[](const int &sub) 
{ 
    if (sub < 0 || sub >= size) 
     subError(); 
    else 
     return rowData[sub]; 
} 

template <class T> 
void RowAray<T>::setData(int row, T value){ 
    //used to fill array with random 2 digit #s 
     *(rowData + row) = value; 
} 

#endif /* ROWARAY_H */ 

Table.h

#ifndef TABLE_H 
#define TABLE_H 

#include "RowAray.h" 

template <class T> 
class Table{ 
    private: 
     int szRow; 
     int szCol; 
     RowAray<T> **records; 

    public: 
     Table(int,int); //used to construct Table object 
     Table(const Table &); 
     ~Table(); //used to deallocate dynamically allocated memory from Table object 
     int getSzRow() const{return szRow;} //used to return row size 
     int getSzCol()const {return szCol;} 
     Table operator+(const Table &); 
     T getRec(int, int) const; //used to return inserted random numbers of 2d arrays 
}; 

template <class T> 
Table<T>::Table(int r, int c){ 
    //Set the row size 
    this->szRow = r; 
    //Declare the record array 
    records = new RowAray<T>*[this->szRow]; 
    //Size each row 
    this->szCol = c; 
    //Create the record arrays 
    for(int i=0;i<this->szRow;i++){ 
     records[i]=new RowAray<T>(this->szCol); 
    } 
} 

template <class T> 
Table<T>::Table(const Table &Tab){ 
    szRow=Tab.getSzRow(); 
    szCol=Tab.getSzCol(); 
    records = new RowAray<T>*[szCol]; 

    for(int i = 0; i < this->szCol; i++){ 
     records[i] = new RowAray<T>(szRow); 
    } 

    //set elements = to random value 
    for(int row = 0; row < szRow; row++){ 
     for(int col = 0; col < this->szCol; col++){ 
      int value = Tab.getRec(row, col); 
      records[col]->setData(row,value); 
     } 
    } 


} 

template <class T> 
T Table<T>::getRec(int row, int col) const{ 
    //if else statement used to return randomly generated numbers of array 
    if(row >= 0 && row < this->szRow && col >= 0 && col < this->szCol){ 
     return records[row]->getData(row); 
    }else{ 
     return 0; 
    } 
} 

template <class T> 
Table<T>::~Table(){ 
    //Delete each record 
    for(int i=0;i<this->szRow;i++){ 
     delete records[i]; 
    } 
    delete []records; 
} 

template <class T> 
Table<T> Table<T>::operator+(const Table &Tab){ 
    Table temp(Tab.getSzRow(), Tab.getSzCol()); 

    //set elements = to random value for operation to 
    for(int row=0; row < szRow; row++){ 
     for(int col=0; col < szCol; col++){ 
      int value = getRec(row, col) + Tab.getRec(row, col); 
      temp.records[col]->setData(row,value); 
     } 
    } 
    return temp; 
} 

#endif /* TABLE_H */ 

main.cpp

#include <cstdlib> 
#include <ctime> 
#include <iostream> 
#include <iomanip> 
using namespace std; 

//User Libraries 
#include "Table.h" 

//Global Constants 

//Function Prototype 
template<class T> 
void prntRow(T *,int); 
template<class T> 
void prntTab(const Table<T> &); 

//Execution Begins Here! 
int main(int argc, char** argv) { 
    //Initialize the random seed 
    srand(static_cast<unsigned int>(time(0))); 

    //Declare Variables 
    int rows=3,cols=4; 

    //Test out the Row with integers and floats 
    RowAray<int> a(3); 
    RowAray<float> b(4); 
    cout<<"Test the Integer Row "<<endl; 
    prntRow(&a,3); 
    cout<<"Test the Float Row "<<endl; 
    prntRow(&b,4); 

    //Test out the Table with a float 
    Table<float> tab1(rows,cols); 
    Table<float> tab2(tab1); 
    Table<float> tab3 = tab1 + tab2; 

    cout<<"Float Table 3 size is [row,col] = Table 1 + Table 2 [" 
      <<rows<<","<<cols<<"]"; 
    prntTab(tab3); 

    //Exit Stage Right 
    return 0; 
} 

template<class T> 
void prntRow(T *a,int perLine){ 
    cout<<fixed<<setprecision(1)<<showpoint<<endl; 
    for(int i=0;i<a->getSize();i++){ 
     cout<<a->getData(i)<<" "; 
     if(i%perLine==(perLine-1))cout<<endl; 
    } 
    cout<<endl; 
} 

template<class T> 
void prntTab(const Table<T> &a){ 
    cout<<fixed<<setprecision(1)<<showpoint<<endl; 
    for(int row=0;row<a.getSzRow();row++){ 
     for(int col=0;col<a.getSzCol();col++){ 
      cout<<setw(8)<<a.getRec(row,col); 
     } 
     cout<<endl; 
    } 
    cout<<endl; 
} 

Antwort

0

Sie Fehler von der Linie 85 von Table.h stammt, in Sie + Betreiber Überlastung:

temp.records[col]->setData(row,value); 

wirklich

temp.records[row]->setData(col,value); 

Neben sollte aus Ich habe einen weiteren Fehler in derselben Datei in Zeile 62 (Methode Table<T>::getRec(int row, int col)) entdeckt:

return records[row]->getData(row); 

sollte

return records[row]->getData(col); 

Abgesehen von diesen Problemen sein, würde ich Ihnen sehr empfehlen, Ihren Code zu überdenken und neu zu strukturieren (vielleicht könnten Sie auch einen Code-Review versuchen), da ein großer Teil von es ist meiner Meinung nach überflüssig und einige Dinge könnten problematisch werden, wenn Sie das Projekt erweitern (zum Beispiel RowAray 's Konstruktor nimmt eine T colSize als Parameter, wo Sie wahrscheinlich eine int oder besser eine size_t verwenden sollten. Dieser Code funktioniert nicht, wenn T nicht implizit in einen Integer-Typ konvertiert werden kann.

+0

Vielen Dank! es funktionierte. Können Sie erklären, warum diese Zeilen den Segmentierungsfehler verursacht haben? Auch ich muss dieser Struktur für Hausaufgaben folgen. Mir ist klar, dass einiges davon sinnlos ist, aber ich muss der Dateistruktur folgen. – EggplantMachina

+0

@EggplantMachina Sicher. Ihre Tabellen haben 3 Zeilen und 4 Spalten. Wenn Ihre Iterator-Variable "col" ihren maximalen Wert erreicht, ist "temp.records [col]" dasselbe wie "temp.records [3]". Da 'temp.records' jedoch nur 'temp.getSzRow()' Einträge enthält, was in diesem Fall 3 ist, ist der Zugriff auf das dritte Element außerhalb der Grenzen. –

Verwandte Themen