Ошибка сегментации в перегруженном операторе >> - PullRequest
1 голос
/ 27 февраля 2011

Я пытаюсь написать код для ортогонально связанной разреженной матрицы.

Вот вопрос:
Альтернативное связанное представление для разреженных матриц использует узлы, которые имеют поля down, right, row, col и value. Каждая ненулевая запись разреженной матрицы представлена по узлу. Нулевые члены не хранятся в явном виде. Узлы связаны между собой, образуя два круговых списка. Первый список, список строк, составляется путем связывания узлов по строкам и внутри строк по столбцам с использованием правого поля. Второй, список, список столбцов, составляется путем связывания узлов через поле вниз. В этом списке узлы связаны столбцами, а внутри столбцов - строками. Эти два списка имеют общий заголовочный узел. Кроме того, узел добавляется в размеры матрицы.

Входной файл выглядит так:

// Матрица A

4 4 7
1 1 2
1 4 1
2 2 7
3 1 9
3 3 8
4 2 4
4 3 5

// Матрица B

4 4 5
1 3 4
2 1 6
2 3 3
3 2 5
4 4 9

Это мой код для оператора >>:

istream& operator>>(istream& in, OrthogonalLinkedSparseMatrix& x){

    in >> x.numRows >> x.numCols >> x.numTerms;
    in >> x.currentNode->row >> x.currentNode->col >> x.currentNode->value;
    x.push_back(x.currentNode);
    if((x.currentNode->row == 1)&&(x.currentNode->col == 1)){

        x.hnode->right = x.currentNode;
        x.hnode->down = x.currentNode;
    }
    if(x.currentNode->col == 1){
        x.hnode->down = x.currentNode;
    }
    if(x.currentNode->row == 1){
        x.hnode->right = x.currentNode;
    }

    for (int i = 2; i <= x.numTerms; i++) {

        in >> x.currentNode->row >> x.currentNode->col >> x.currentNode->value;

        x.push_back(x.currentNode);

    }


    return in;

}

Отлично компилируется. Но когда я пытаюсь запустить его, я получаю ошибку ошибки сегментации.
Может кто-нибудь помочь ?? Огромное спасибо!

Вот OrthogonalLinkedSparseMatrix.h:

#ifndef O_L_SPARSE_MATRIX_H

#define O_L_SPARSE_MATRIX_H



#include <iostream>

#include <fstream>

#include "node.h"

#include "myExceptions.h"



using namespace std;



class OrthogonalLinkedSparseMatrix;

ostream& operator<< (ostream&, OrthogonalLinkedSparseMatrix&);

istream& operator>> (istream&, OrthogonalLinkedSparseMatrix&);



class OrthogonalLinkedSparseMatrix{

public:

    friend ostream& operator<<(ostream& out, OrthogonalLinkedSparseMatrix& x);

    friend istream& operator>>(istream& in, OrthogonalLinkedSparseMatrix& x);

    OrthogonalLinkedSparseMatrix(){}

    ~OrthogonalLinkedSparseMatrix(){}

    void transpose(OrthogonalLinkedSparseMatrix &b);

    void add(OrthogonalLinkedSparseMatrix &a, OrthogonalLinkedSparseMatrix &c);

    void push_back(matrixNode *&mat_Node);

    void setDowns(matrixNode *&mat_Node);

private:

    matrixNode *hnode;

    int numRows, numCols, numTerms;

    matrixNode *currentNode;

    matrixNode *previousNode;

    matrixNode *nextNode;

};

 // code for operator >> & <<, etc goes here, but everything's commented out except operator >>  

#endif

РЕДАКТИРОВАТЬ: я включаю оператор <<, а также: </p>

    ostream& operator<<(ostream& out, OrthogonalLinkedSparseMatrix& x){

    if(x.numTerms == 0){

        out << "No non-zero terms" << endl;

        return out;

    }

    out << x.numRows << x.numCols << x.numTerms << endl;

    for (int i = 0; i < x.numTerms; i++) {

        out << x.currentNode->row << x.currentNode->col << x.currentNode->value << endl;

    }

    return out;

}

1 Ответ

2 голосов
/ 27 февраля 2011

Я думаю, что ваша проблема с currentNode. Вам не нужно это как переменную класса, и вместо этого вы должны создавать новую каждый раз, когда читаете входные данные из потока. Например,

istream& operator>>(istream& in, OrthogonalLinkedSparseMatrix& x)
{
    in >> x.numRows >> x.numCols >> x.numTerms;

    int inRow, inCol, inValue;
    in >> inRow >> inCol >> inValue;         // Get the values from input

    // note: this allocates a NEW matrixNode on the heap, and pushes a pointer into the matrix.
    x.push_back(new matrixNode(inRow, inCol, inValue));

    if(x.currentNode->col == 1){
        x.hnode->down = x.currentNode;
    }
    if(x.currentNode->row == 1){
        x.hnode->right = x.currentNode;
    }

    for (int i = 2; i <= x.numTerms; i++) 
    {
        in >> inRow >> inCol >> inValue;         // Get the values from input

        // note: this allocates a NEW matrixNode on the heap, and pushes a pointer into the matrix.
        x.push_back(new matrixNode(inRow, inCol, inValue));
    }

    return in;
}

Несколько вещей, на которые стоит обратить внимание:

  • Каждый раз, когда вызывается push_back(), включается новый matrixNode. В вашей реализации один и тот же узел всегда добавлялся и, вероятно, никогда не инициализировался.
  • Я предположил, что у matrixNode есть конструктор, который принимает 3 аргумента. Это должно быть легко добавить.

В общем, управление указателями самостоятельно очень опасно и подвержено утечкам памяти. В этом случае важно, чтобы вы вызывали delete для каждого указателя, когда он вам больше не нужен. Скорее всего, вы захотите сделать это в вашем деструкторе.

EDIT: Также похоже, что hnode может использоваться с недопустимым указателем. Убедитесь, что вы присвоили / создали этот указатель matrixNode перед его использованием.

...