重载<<导致valgrind错误

时间:2014-11-15 05:11:05

标签: c++ operator-overloading valgrind

我正在尝试重载<<运算符按我的意愿给出输出。当我运行以下代码时,它编译没有任何问题

#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
}

如果没有&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ENDL ;.存在&lt;&lt; ENDL;但是我得到了seg错误和以下valgrind错误。我不确定为什么会抛出这个错误

Valgrind的:

==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

1 个答案:

答案 0 :(得分:3)

你需要

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 ;
}