过载<<导致瓦尔格林德误差

Overloading << results in valgrind error

本文关键字:lt 林德 误差 过载      更新时间:2023-10-16

我正在尝试重载<<运算符以根据需要提供输出。当我运行以下代码时,它可以毫无问题地编译

#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
template <class type>
class matrix
{
public:
  string _name;
  int _rows, _columns;
  type** _data;
  matrix()
  {
    _name = "A";// Default name is A
    _rows = 1;
    _columns = 1;
    _data = new type*[_columns]; 
    _data[0] = new type[_rows*_columns];
    _data[0][0] = 0;     
  }
  matrix(int rows, int columns, string name)
  {
    _rows = rows;
    _columns = columns;
    _name = name; 
    _data = new type*[_columns]; 
    _data[0] = new type[_rows*_columns];
    for (int i=0; i<_columns; i++)
      {
    _data[i] = _data[0] + i*_rows; 
      }
    for (int i=0; i<_columns; i++) //Initialise matrix elements to zeros 
      {for (int j=0; j<_rows; j++)
      {
        _data[i][j] = 0;
      }
      }
  }

  ~matrix()         // Destructor
  {
    _name = " ";
    _rows = 0;
    _columns = 0;
    delete [] _data[0];
    delete [] _data;
  }

};
template<class type>
ostream &operator<<(ostream &os, matrix<type> &mat)
{
  string name = mat._name;
  int columns = mat._columns;
  int rows = mat._rows;
  cout<<"Matrix "<<name<<endl;
  cout<<"Col: "<<columns<<" Row: "<<rows<<endl;
  for (int i=0; i<rows; i++)  
    {for (int j=0; j<columns; j++)
     {
       cout<<mat._data[j][i];
       cout<<" ";
     }
       cout<<endl;
     } 
  cout<<endl;
}  
main(){
  // constructor
  matrix<float> A(2,2, "A");
  cout << A << endl; //Problematic
}

如果没有 endl; <<,此代码将完美运行和输出。在<<面前;但是我得到了赛格错误和以下瓦尔格林德错误。我不确定为什么会抛出此错误

瓦尔格林德:

==3862== Invalid read of size 4
==3862==    at 0x40D4FA7: std::basic_ostream<char, std::char_traits<char> >&         std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==3862==    by 0x40D44AD: std::ostream::operator<<(std::ostream& (*)(std::ostream&))     (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==3862==    by 0x8048B2E: main (check.cpp:85)
==3862==  Address 0xfffffff5 is not stack'd, malloc'd or (recently) free'd
==3862== 
==3862== 
==3862== Process terminating with default action of signal 11 (SIGSEGV)
==3862==  Access not within mapped region at address 0xFFFFFFF5
==3862==    at 0x40D4FA7: std::basic_ostream<char, std::char_traits<char> >&     std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char>     >&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==3862==    by 0x40D44AD: std::ostream::operator<<(std::ostream& (*)(std::ostream&))     (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==3862==    by 0x8048B2E: main (check.cpp:85)
==3862==  If you believe this happened as a result of a stack
==3862==  overflow in your program's main thread (unlikely but
==3862==  possible), you can try to increase the size of the
==3862==  main thread stack using the --main-stacksize= flag.
==3862==  The main thread stack size used in this run was 1048576.
==3862== 
==3862== HEAP SUMMARY:
==3862==     in use at exit: 38 bytes in 3 blocks
==3862==   total heap usage: 3 allocs, 0 frees, 38 bytes allocated

PS:我正在使用g ++编译cpp文件,如下所示:

>g++ -g -o a check.cpp

你需要有

return os ;

在重载<< operator中使用os而不是cout所有位置,以便将类对象序列化为任何ostream对象

template<class type>
ostream &operator<<(ostream &os,   const matrix<type> &mat)
                                /*  ~~~ Use const ref 
                                 to avoid copies and ensuring 
                                you aren't modifying anything on mat object */
{
   // ...
      os << "Matrix "<<name <<endl;
   //~~~
      os << mat._data[j][i];
   // ~~~
   // etc...
   return os ;
}