Segmentation fault



  • Ja, die ersten drei Zeilen sind die Construktoren deiner Matrix-Klasse. Aber für die Fehlersuche dürfte es hilfreicher sein zu wissen, was sie eigentlich machen (in deinem Programm besonders der zweite -"Matrix(int rows,int cols);").

    PS: Sorry für die Verwirrung - das ist die Macht der Gewohnheit 😉



  • Die ersten drei Zeilen sind definitionen von Konstruktoren (Ctor's) und die vierte zeile ist der dtor



  • Naja

    Matrix<int> M(x,y)
    

    definiert eine Matrix M in meinem Programm mit x Zeilen und y Spalten

    P.S. sorry dass ich mich so dumm anstelle - vielleicht haette ich waehrend meinem Studium doch den Java-Kurs machen sollen, dann braeuchte ich nicht von vorne anfangen 🙂



  • Lagrange schrieb:

    Naja

    Matrix<int> M(x,y)
    

    definiert eine Matrix M in meinem Programm mit x Zeilen und y Spalten

    Und wie?

    (Auf gut Deutsch: Zeig doch mal bitte den Funktionsrumpf zu diesem Konstruktor)



  • Sorry, verstehe leider wirklich nicht, was du genau sehen willst. Ich haenge hier nochmal ein komplettes Programm an, was auch funktioniert und die Funktion Matrix benutzt. Sonst wuesste ich leider wirklich nicht, was ich dir noch schicken soll. Ich lade einfach den Header (bamatrix.h - einen Teil davon hast du schon gesehen - das war die Sache mit dem Ctor) und dann definiere ich meine Matrix mit

    Matrix<int> M(x,y)
    

    Und greife auf die einzelnen Eintraege mit M[a][b] zu.

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
    #include"bamatrix.h"
    
    int main()
    {
    
    int index = 0;
    Matrix<int> M(2,2);
    std::vector<Matrix<int> > Store(index); 
    
       for(int i = 0; i<4; i++)
       {
       M[0][0] = i;
       M[0][1] = i;
       M[1][0] = i;
       M[1][1] = i;
       Store.push_back(M);
       }
    
    Matrix<int> K(2,2);
    K = Store[3];
    
    cout << K[1][1] << endl;
    }
    


  • Lagrange schrieb:

    ...bamatrix.h - einen Teil davon hast du schon gesehen - ...

    Ja - aber wir wollen noch mehr davon sehen ! 😃

    Und zwar genau den Teil, der mit

    Matrix<T>::Matrix( int rows, int cols ) {
    

    anfängt 😃

    Übrigens:

    Lagrange schrieb:

    ...

    ...
    int index = 0;
    std::vector<Matrix<int> > Store(index); 
    ...
    

    Das brauchst Du nicht - index ist überflüssig, wenn Du keine vorreservierte Größe möchtest:

    ...
    std::vector<Matrix<int> > Store;
    ...
    

    Macht dasselbe.

    Gruß,

    Simon2.



  • Lagrange schrieb:

    Sorry, verstehe leider wirklich nicht, was du genau sehen willst.

    Ich würde gerne sehen, was du im Inneren des Konstruktors "Matrix::Matrix(int rows,int cols)" machst.



  • So auch wenn das jetzt ein bischen nach Spam aussieht, aber ich schicke dir jetzt mal das ganze Programm bamatrix.h (das programm ist aber nicht von mir - das war bei meinem Buch zum lernen von C++ dabei)

    #ifndef _BAMATRIX_H
    #define _BAMATRIX_H
    
    #include <iostream>
    #include <cstdlib>
    #include <vector>
    using namespace std;
    
    template <class ItemType>
    class Matrix
    {
      public:
        Matrix();
        Matrix( int rows, int cols );  // size rows x cols
        Matrix ( const Matrix & mat);  // copy constructor
        ~Matrix();
    
        // Assignment
        const Matrix& operator = (const Matrix & Rmat);
    
        // Accessors
        int numrows( ) const;  // number of rows
        int numcols( ) const;  // number of columns
        const vector<ItemType>& operator[] (int index) const;
    
        // Modifiers
        vector<ItemType>& operator[] (int index);
        void resize( int newRows, int newCols ); // resizes matrix to
                                                 // newRows x newCols
    
      private:
        int nRows;    // # of rows (capacity)
        int nCols;    // # of cols (capacity)
        vector< vector <ItemType> > Mtrx; // the matrix of items
    
        void check_range (int index) const;
    };  // end Matrix class specification
    
    ///////////////////////////// Matrix class implementation
    template <class ItemType>
    Matrix<ItemType>::Matrix()
      : nRows(0), nCols(0),
        Mtrx(0)
    { }
    
    template <class ItemType>
    Matrix<ItemType>::Matrix( int rows, int cols )
      : nRows(rows), nCols(cols),
        Mtrx(rows)
    {
       for (int r=0; r<nRows; r++)
          Mtrx[r].resize(cols);
    }
    
    template <class itemType>
    Matrix<itemType>::Matrix(const Matrix<itemType> & mat)
        : nRows(mat.nRows),
          nCols(mat.nCols),
          Mtrx(mat.nRows)
    {
        // copy rows
        for(int i = 0; i < nRows; i++)
          Mtrx[i] = mat.Mtrx[i];
    }
    
    template <class ItemType>
    Matrix<ItemType>::~Matrix()
    {  /* defaults to Vector destructor! */ }
    
    template <class itemType>
    const Matrix<itemType> &
    Matrix<itemType>::operator = (const Matrix<itemType> & Rmat)
    {
        if (this != &Rmat)   // don't assign to self!
        {
            Mtrx.resize(Rmat.nRows); // resize to proper # of rows
            nRows = Rmat.nRows;      // set dimensions
            nCols = Rmat.nCols;
    
            // copy rows
            for(int i=0; i < nRows; i++)
            {
                Mtrx[i] = Rmat.Mtrx[i];
            }
        }
        return *this;
    }
    
    template <class ItemType>
    vector<ItemType>&
    Matrix<ItemType>::operator[] (int index)
    {
       check_range(index);
       return Mtrx[index];
    }
    
    template <class ItemType>
    void
    Matrix<ItemType>::resize(int newRows, int newCols)
    {
        Mtrx.resize(newRows);
    
        for(int r=0; r < newRows; r++)
            Mtrx[r].resize(newCols);
        nRows = newRows;
        nCols = newCols;
    }
    
    template <class ItemType>
    int
    Matrix<ItemType>::numrows( ) const
    {  return nRows; }
    
    template <class ItemType>
    int
    Matrix<ItemType>::numcols( ) const
    {  return nCols; }
    
    template <class ItemType>
    const vector<ItemType>&
    Matrix<ItemType>::operator[] (int index) const
    {
       check_range(index);
       return Mtrx[index];
    }
    
    template <class ItemType>
    void
    Matrix<ItemType>::check_range (int index) const
    {
       if (index < 0 || index >= nRows )
          {
          cerr << "\n***ERROR: index [" << index
               << "] out of range (" << 0
               << ".." << (nRows-1) << ")\n";
          exit(1);
          }
    }
    #endif
    


  • Hi,

    also ich habe das Teil mal importiert und muss sagen: Bei mir compiliert und läuft das tadellos ! (habe den gcc)

    Allerdings habe ich die überflüssigen C-Header weggelassen - das sollte aber eigentlich keinen Segfault erzeugen/verhindern.

    Das ist natürlich ein schwacher Trost und auch eine schwache Aussage. Es könnte sein, dass bei mir undefiniertes Verhalten nicht negativ auffällt, aber ich sehe so auf die Schnelle eigentlich nichts, was falsch oder seltsam aussieht.

    Gruß,

    Simon2.



  • mmh wie gesagt, solange ich es in einem kleinen Programm laufen lassen, funktioniert es auch einwandfrei, aber sobald ich es in meinem eigentlichen Program laufen lasse - ist dann schon etwas umfangreicher - produziert er den obengenannten error. Aergerlich - trotzdem vielen vielen Dank fuer die Muehe die du dir mit mir gegeben hast - ich bin auf jeden Fall ein ganzes Stueckchen durch dich weiter gekommen



  • Lagrange schrieb:

    ...sobald ich es in meinem eigentlichen Program laufen lasse - ist dann schon etwas umfangreicher - produziert er den obengenannten error....

    🙄
    Also ehrlich gesagt, komme ich mir ein wenig verhonepiepelt vor - Du präsentierst uns ein absolut fehlerfrei laufendes Programm und wir sollen Dir sagen, wodurch den Fehler in einem anderen Programm von Dir stammt ?

    Ich würde Dir Debugging ans Herz legen: Versuche rauszubekommen, in welchem Programmteil der Fehler kommt und dann versuchen, das Programm soweit abzustrippen, dass es zwar den Fehler noch produziert, es aber übersichtlich ist.

    Meine Vermutung: Beim resize() (oder anlegen) ist eine Variable nicht initialisiert, weswegen vector angewiesen wird, 868787658658239879234 Bytes Speicher anzufordern....
    Aber Genaueres kann man nur mit dem Code (der den Fehler produziert und trotzdem überschaubar ist) sagen.

    Gruß,

    Simon2.



  • Sorry, aber ich habe doch die ganze Zeit gesagt, dass es komischerweise in dem grossen Programm nicht funktioniert

    Ich habe dann mit "cout" - die stelle ausmachen koennen, wo er den Fehler produziert. Und dieser Fehler tritt genau an der Stelle auf, wo ich:

    std::vector<Matrix<int> > Store
    

    schreibe! Lasse ich diesen Teil weg - oder besser ersetze ihn einfach durch etwas anderes, funktioniert das Programm einwandfrei - tut dann nur nicht mehr, das was es eigentlich soll. Also muss das schon irgendwie an diesem Ausdruck liegen. Und da er den Fehler (mit g++):

    *** glibc detected *** malloc(): memory corruption (fast): 0x08fc8fa8 ***

    produziert, dachte ich dass ich in der Zeile wieder etwas benutzt habe, was sich nicht mit c++ vertraegt - wie beim letzten mal (siehe anfang von diesem Thema), als der gleiche Fehler aufgetreten ist.
    Ich glaube nicht, dass es irgendwas mit dem restlichen Programm zu tun hat, weil ich die Matrix Store, dann lange nicht mehr benutze - erst gegen ende wieder.



  • Hi,

    habe ich vielleicht überlesen - ist aber auch egal.

    Äh, verstehe ich richtig: Das Programm würde den Segfault liefern, wenn Du das Programm hinter der Zeile

    Lagrange schrieb:

    ...

    std::vector<Matrix<int> > Store
    

    ...

    (Da ist doch bestimmt ein ";" hinter, oder ?)
    abschneiden würdest ?

    Probier das doch mal aus - und wenn, dann zeig doch mal das Programm bis dahin.

    Gruß,

    Simon2.



  • Nur eine kleine Randbemerkung: Der Copy-Ctor (für Laien: Matrix(const Matrix& mat); , Destruktor und operator= sind für diese Klasse eigentlich überflüssig - du hast keine selbstverwalteten Daten, also reicht die implizit bereitgestellte Version dieser Methoden völlig für deine Zwecke aus.

    Ansonsten: Zeig doch mal ein Minimalprogramm - bei dem der Fehler wirklich auftritt.



  • Sorry, dass es so lange gedauert hat, ich musste ersteinmal meinen Erstjahresbericht fertig machen. Nun aber zurueck zum Problem. Ich habe jetzt ein Programm, wo das oben genannte Problem auftritt:

    #include <cstdio>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    #include"bamatrix.h"
    #include <vector>
    
    std::vector<Matrix<int> > Store;
    
    Matrix<int> Cluster(6,3);
    Matrix<int> Coordinates (20,2);
    Matrix<int> matrix1;
    int main()
    {
    
    for(int test = 0; test< 20; test++)
        {
        Coordinates[test][0] = test;
        Coordinates[test][1] = test;
        Coordinates[test][2] = test;
        Coordinates[test][3] = test;
        Coordinates[test][4] = test;
        Coordinates[test][5] = test;
        }
    
    Cluster[0][3] = 4;
    Cluster[1][3] = 6;
    Cluster[2][3] = 2;
    Cluster[3][3] = 4;
    Cluster[4][3] = 1;
    Cluster[5][3] = 3;
    
    int index = 6;
    int sumclustersize = 0;
    
    for(int t = 0; t < index; t++)
    {
    int j1 = 0;
    cout << Cluster[t][3] << endl;
    matrix1.resize(Cluster[t][3],6);
    for(int j2 = sumclustersize; j2 < sumclustersize+Cluster[t][3]; j2++)
        {
    
        matrix1[j1][0] = Coordinates[j2][0];
        matrix1[j1][1] = Coordinates[j2][1];
        matrix1[j1][2] = Coordinates[j2][2];
        matrix1[j1][3] = Coordinates[j2][3];
        matrix1[j1][4] = Coordinates[j2][4];
        matrix1[j1][5] = Coordinates[j2][5];
        j1++;
        }
    j1 = 0;
    sumclustersize = sumclustersize+Cluster[t][3];
    
    Store.push_back(matrix1);
    }
    
    }
    

    Ich bekomme mit g++ folgende Fehlermeldung:
    *** glibc detected *** free(): invalid next size (fast): 0x089142f0 ***
    Aborted

    Sehr komisch ist auch, dass wenn ich "Matrix<int> matrix1;" nicht vor die Main-Funktion setze, sondern ins Programm, bekomme ich einen Segmentation Error und zwar an der Stelle, an der ich versuche die Groesse von matrix1 versuche zu aendern.

    Nocheinmal vielen vielen Dank fuer eure Hilfe



  • Lagrange schrieb:

    Matrix<int> Cluster(6,3);
    Matrix<int> Coordinates (20,2);
    Matrix<int> matrix1;
    [...]
    
    for(int test = 0; test< 20; test++)
        {
        Coordinates[test][0] = test;
        Coordinates[test][1] = test;
        Coordinates[test][2] = test;
        Coordinates[test][3] = test;
        Coordinates[test][4] = test;
        Coordinates[test][5] = test;
        }
    

    Und da wunderst du dich über irgendwas? Du schreibst ja auch deutlich über das Ende des reservierten Speichers hinaus (Coordinates wurd mit 20 Zeilen und 2 Spalten angelegt, du schreibst dort in die 6. Spalte

    (auch die Einträge 'Cluster[x][3]' weiter unten liegen außerhalb des Bereiches, den du vorher angefordert hast)



  • Ich bin doch so ein Affe - ich hatte die Matrizen zunaechst fuer eine andere Funktion programmiert und dann vergessen die Groesse zu aendern. Aber warum hat mir dann der Compiler nicht in Zeile 22 eine Fehlermeldung geben. Ich glaube ich bin einfach zu dumm fuer c++ 🙂

    Nochmal danke fuer deine Hilfe - bis spaeter 😉



  • Wieso sollte er? vector<>::op[] hat keine Bereichsüberprüfung und aus Sicht des Compilers ist nichtmal klar, ob die Breite an dieser Stelle immer noch 2 ist (oder gar was die 2 bei Ctor-Aufruf bedeutet). Du könntest höchstens at() anstelle des Operators nutzen, dann beschwert sich das Programm an der richtigen Stelle.


  • Mod

    Die gerechte Strafe für magische Konstanten 😉


Anmelden zum Antworten