【问题标题】:Segmentation fault overloading ostream (<<)分段错误过载 ostream (<<)
【发布时间】:2017-03-06 21:48:13
【问题描述】:

所以我正在练习 C++ 中的编码,并且我正在尝试为具有相关重载操作的矩阵(存储为数组)编写一个类。

我已经定义了类并试图重载

任何帮助将不胜感激。

这是我的代码:

#include<iostream>
#include<stdlib.h> // for c style exit
using namespace std;

class matrix
{
  // Friends
  friend ostream & operator<<(ostream &os, const matrix &mat);
  friend istream & operator>>(istream &is, matrix &mat);

private:
  double *mdata;
  int rows,columns;
public:
  // Default constructor
  matrix(){mdata=0; rows=columns=0;}
  // Parameterized constructor
  matrix(int m, int n){mdata = new double[ m*n ]; rows = m; columns = n;}
  // Copy constructor
  matrix(matrix &mat)
  // Destructor
  ~matrix(){delete[] mdata; cout<<"Destructing array."<<endl;}
  // Access functions
  int getrows() const {return rows;} // Return number of rows
  int getcols() const {return columns;} // Return number of columns
  int index(int m, int n) const // Return position in array of element (m,n)
  {
    if(m>0 && m<=rows && n>0 && n<=columns) return (n-1)+(m-1)*columns;
    else {cout<<"Error: out of range"<<endl; exit(1);}
  }
  double & operator()(int m, int n)const {return mdata[index(m,n)];}
  // Other access functions go here
  double & operator[](int i) {return mdata[i];}
  // Other functions 
  // Copy  Assignment operator
  matrix & operator=(matrix &mat);
};

// Member functions defined outside class
matrix::matrix(matrix &mat){
  rows = mat.getrows();
  columns = mat.getcols();
  for(int j = 0; j<rows*columns; j++){mdata[j] = mat[j];}
 }

matrix & matrix::operator=(matrix &mat){
  if (&mat == this) return *this;

  delete[] mdata; rows = 0; columns = 0;

  rows = mat.getrows(); columns = mat.getcols();
  if(rows>0&&columns>0){
    mdata = new double[(columns-1) + (rows-1)*columns + 1];
    for(int j = 0; j<rows*columns; j++){mdata[j] = mat[j];}
  }
  return *this;
}


// Overload insertion to output stream for matrices
ostream & operator<<(ostream &os, const matrix &mat){
  for(int j = 0;j<mat.rows;j++){
    for(int k = 0;k<mat.columns;k++){
      os << mat(j+1,k+1) << " ";
   }
    os << endl;
 }
  return os;
}

// Main program

int main(){

  // Demonstrate default constructor
  matrix a1;
  cout<<a1;

  // Parameterized constructor
  const int m(2),n(2);
  matrix a2(m,n);
  // Set values for a2 here
  a2[0] = 1; a2[1] = 2; a2[2] = 3; a2[3] = 4;
  // Print matrix a2
  cout<<a2;


  // Deep copy by assignment: define new matrix a3 then copy from a2 to a3
  matrix a3(m,n);
  cout<<a3;
  a3=a2;
  cout<<a3;
  // Modify contents of original matrix and show assigned matrix is unchanged here
  a2[0] = 5;
  cout<<a2;
  cout<<a3; //here is where segmentation fault occurs
  return 0;
}

【问题讨论】:

  • 我建议先修复复制构造函数和赋值运算符。
  • 然后用调试器运行,因为你的代码充满了琐碎的错误。
  • 我已经定义了类——你没有。只需一个两行 main() 程序,这个矩阵类就可以一蹴而就。 { matrix m(1,2); matrix m2=m;}
  • 我无法重现错误(在我添加编译器所需的分号之后)。这是一个最小的例子吗?
  • @user7631642 已经说过您的复制构造函数存在大问题。你没看到吗?您的赋值运算符中还有一个迫在眉睫的错误。 matrix m; matrix m2(1,2); m = m2; 如果我可以用这些小例子造成破坏,也许你应该先解决这些问题。

标签: c++ ostream fault


【解决方案1】:

您似乎超出了矩阵的限制。您应该删除 +1ij...

for(int j = 0;j<mat.rows;j++){
    for(int k = 0;k<mat.columns;k++){
      os << mat(j,k) << " ";
   }

当一个数组有 3 个元素时,这意味着您可以访问这 3 个元素:

array[0]
array[1]
array[2]

但不是array[3],它是数组中长度为 3 的第 4 个元素。

根据经验,当您获得segmentation fault 时,您应该使用gdbvalgrind 运行您的程序。这些工具通常会为您提供非常有价值的信息,以发现代码中内存访问错误的根本原因。

【讨论】:

  • 数组的长度是4。这可以通过在分段错误发生之前多次使用ostream并按预期输出4个元素的事实来证实。
  • 我写了3作为例子。如果您的数组长度为 4,那么您正在尝试访问第 5 个元素 (array[4])。分段错误不是自动的,即。您的程序可以多次运行而不会崩溃,这并不意味着您没有做危险的事情。这取决于许多超出此问题范围的条件。
【解决方案2】:

您需要将 FUNCTION 设为类矩阵的 friend,因为它无法访问 columnsrows,因为它们是私有成员。重载operator&lt;&lt;operator&gt;&gt; 时的典型错误。永远不要忘记friend

【讨论】:

  • 运算符
  • 我错过了声明,抱歉。
猜你喜欢
  • 2013-03-25
  • 2013-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多