重载运算符中的分段错误>>

Posted

技术标签:

【中文标题】重载运算符中的分段错误>>【英文标题】:Segmentation fault in overloaded operator>> 【发布时间】:2011-02-27 18:45:55 【问题描述】:

我正在尝试为正交链接稀疏矩阵编写代码。

问题来了: 稀疏矩阵的另一种链接表示使用具有 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

编辑:我也包括操作员

    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;


【问题讨论】:

您是否尝试过使用调试器来找出导致 seg 错误的确切原因?调试器是你的朋友。 另外,在调用operator&gt;&gt; 之前,OrthogonalLinkedSparseMatrix 是如何创建/设置的? currentNode 指针是否正确分配给分配的对象? 我已经设置好 currentNode 看起来像这样:OrthogonalLinkedSparseMatrix *currentNode; 这是OrthogonalLinkedSparseMatrix的私有属性 currentNode 是指向OrthogonalLinkedSparseMatrix 的指针?可以贴出OrthogonalLinkedSparseMatrix声明的相关部分吗? 【参考方案1】:

我认为您的问题与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 很重要。您很可能希望在析构函数中执行此操作。

编辑: 看起来hnode 可能正在与无效指针一起使用。确保在使用之前分配/创建此 matrixNode 指针。

【讨论】:

好的,所以我改变了我的操作员>>。现在我的操作员> 中创建新节点,我如何从 operator 访问它们 @Ariana,不知道push_back() 到底做了什么,很难说。你应该问另一个问题,解释push_back() 做了什么并显示你现在拥有的代码。然后,我们可以再次为您提供帮助:-) 现在,push_back() 已被注释掉,所以此时它什么都不做。 @Ariana,如果您从不存储您创建的节点,那么您以后将无法访问它们。您需要将指针存储到容器中,然后在operator&lt;&lt; 中将它们读回。再问一个问题,我们会为您提供帮助。

以上是关于重载运算符中的分段错误>>的主要内容,如果未能解决你的问题,请参考以下文章

不能重载 Raku 中的 >> 运算符

C ++中的运算符重载编译错误

C ++分段在进行矩阵乘法时出错

重载输出运算符时出现错误 c2440 错误

C#中的运算符重载

c ++模板类中的运算符重载