2016-07-10 8 views
0

Es gibt andere Beiträge über häufige Ursachen von Segmentierungsfehlern, aber ich glaube nicht, dass das integrierte Array-Objekt, das ich hier erstellt habe (result), doesn ' t gehe außerhalb der Grenzen, wenn ich ihm Werte zuweise.
Ich denke, dass dies für Menschen in der Zukunft hilfreich sein könnte, die Arrays nicht außerhalb der Grenzen haben, und ich habe auch nicht viel Zeuge 2D-integrierte Array-Objekte gesehen - Beispiele, die ich gesehen habe, sind fast ausschließlich Vektoren oder std: Array-Objekte.Segmentierungsfehler, aber Array-Objekt geht nicht außerhalb der Grenzen (C++)

Hier ist runnable, ein entsprechender Code:

matrix.h

#ifndef MATRIX_H 
#define MATRIX_H 

#include <initializer_list> 
using std::initializer_list; 

typedef unsigned int uint; 

class Matrix { 

    public: 

    Matrix(uint rows, uint cols); 
    ~Matrix(); 
    Matrix add(double s) const; 
    const uint numRows() const; 
    const uint numCols() const; 
    double & at(uint row, uint col); 
    const double & at(uint row, uint col) const; 

    private: 

    uint rows, cols; 
    double ** matrix; 

    void makeArray() { 
     matrix = new double * [rows]; 
     for(uint i = 0; i < rows; ++i) { 
     matrix[i] = new double [cols]; 
     } 
    } 

}; 

#endif 

matrix.cpp

#include "matrix.h" 
Matrix::Matrix(uint rows, uint cols) { 
    //Make matrix of desired size 
    this->rows = rows; 
    this->cols = cols; 

    makeArray(); 

    //Initialize all elements to 0 
    for(uint i = 0; i < rows; ++i) { 
    for(uint j = 0; j < cols; ++j) { 
     this->matrix[i][j] = 0.0; 
    } 
    } 
} 
Matrix::~Matrix() { 
    for(uint i = 0; i < numRows(); ++i) { 
    delete[] matrix[i]; 
    } 
    delete[] matrix; 
} 
const uint Matrix::numRows() const { 
    return this->rows; 
} 

const uint Matrix::numCols() const { 
    return this->cols; 
} 

double & Matrix::at(uint row, uint col) { 
    return matrix[row][col]; 
} 

const double & Matrix::at(uint row, uint col) const { 
    return matrix[row][col]; 
} 

Matrix Matrix::add(double s) const { 
    uint r = this->numRows(); 
    uint c = this->numCols(); 

    Matrix * result; 
    result = new Matrix(r, c); 

    for(uint i = 0; i < r; ++i) { 
    for(uint j = 0; j < c; ++j) { 
     result->at(i,j) = (this->at(i,j)) + s; 
    } 
    } 

    return * result; 
} 

main.cpp

#include <iostream> 
#include <cstdlib> 
#include "matrix.h" 

using namespace std; 

typedef unsigned int uint; 

int main() { 

    Matrix * matrix; 
    matrix = new Matrix(3, 2); //Works fine 

    double scaler = 5; 

    matrix->at(2,1) = 5.0; //Works fine 

    Matrix r = matrix->add(scaler); //DOESN'T WORK 

    return EXIT_SUCCESS; 
} 

Irgendwelche Ideen, warum die add Funktion einen Segmentierungsfehlerfehler verursacht? Die for-Schleife, die ich benutzte, um das Matrix-Ergebnis-Objekt zu füllen, geht nicht außerhalb der Grenzen, und ich bin nicht vertraut genug mit C++, um zu wissen, was es sonst noch verursachen könnte.
Vielen Dank im Voraus.

+1

Es gibt wahrscheinlich andere Probleme. Versuchen Sie nicht, die dynamische Speicherzuordnung selbst zu verwalten, es sei denn, Sie sind absolut sicher, dass Sie dies tun müssen. –

+1

Sollten wir den Speicherverlust in Ihrem 'add()' - Member ignorieren, konzentrieren wir uns nur auf ein viel größeres Problem, nämlich [Was ist die Regel von 3] (https://stackoverflow.com/questions/4172722/what-is -die-Regel-von-drei)? – WhozCraig

+0

'Matrix * Ergebnis; [...] return * result; 'warum tust du das? Btw Ich sehe keinen guten Grund für ein einzelnes '*' in Ihrem Code – user463035818

Antwort

1

Das Problem ist das Fehlen eines manuell definierten Kopierkonstruktors oder Zuweisungsoperators, da die Klasse eine Ressource (Speicher) verwaltet.

Wenn eine Instanz der Klasse zugewiesen oder zum Erstellen einer Kopie verwendet wird, sind zwei unterschiedliche Objekte das Ergebnis, die auf denselben Speicher verweisen. Wenn diese zwei Objekte, die sich auf denselben Speicher beziehen, zerstört werden, wird der Speicher zweimal freigegeben. Die Folge davon ist undefiniertes Verhalten.

Suchen Sie nach der "Dreierregel" für eine Lösung. In C++ 11 wird dies oft zu einer "Regel von fünf" oder einer "Regel von Null" (was beinhaltet, Techniken zu verwenden, um das Problem an erster Stelle zu vermeiden).

Es gibt auch ein ziemlich signifikantes Problem in der add()-Funktion, da es dynamisch erstellt Matrix, dann gibt eine Kopie davon zurück. Das führt zu einem Speicherverlust, selbst wenn das Problem mit dem Kopieren des Objekts behoben ist. Diese Funktion sieht tatsächlich wie etwas aus, das in einer Garbage-Collection-Sprache geschrieben wäre - das Problem ist, dass C++ keine Garbage Collection ist.

Verwandte Themen