1

So i'm trying to delete the 2D sq_matrix in the destructor. However, it's giving me a memory error:

    *** glibc detected *** ./hw1.out: free(): invalid pointer: 0x0000000000d6ccb0 ***
    ======= Backtrace: =========
    /lib64/libc.so.6[0x31dd675f3e]
    /lib64/libc.so.6[0x31dd678d8d]
    ./hw1.out[0x4011af]
    ./hw1.out[0x400f54]
    /lib64/libc.so.6(__libc_start_main+0xfd)[0x31dd61ed1d]
    ./hw1.out[0x400a69]
    ======= Memory map: ========
    00400000-00402000 r-xp 00000000 fd:02 99359246    
/*                        some memory map here  */
    Aborted (core dumped)

Here's the .h file I put my code in:

#ifndef SQUAREMATRIX_H
#define SQUAREMATRIX_H
#include <iostream>

using namespace std;
template<class T>
    class SquareMatrix{

     public:
      int size;
      T** sq_matrix;

      SquareMatrix(int s){
          size = s;
          sq_matrix = new T*[size];
          for(int h = 0; h < size; h++){
            sq_matrix[h] = new T[size];
          }
      }

      ~SquareMatrix(){
        for(int h = 0; h < size; h++){
            delete[] sq_matrix[h];
        }
         delete[] sq_matrix; 
      } 

      void MakeEmpty(){
         //PRE: n < width of sq matrix
         //POST: first n columns and rows of sq_matrix is zero

      }
      void StoreValue(int i, int j, double val){
          //PRE: i < width; j < height
          //POST: sq_matrix[i][j] has a non-null value
      }
      void Add(SquareMatrix s){
         //PRE: this.SquareMatrix and s are of the same width and height
         //POST: this.SquareMatrix + s
      }
      void Subtract(SquareMatrix s){
         //PRE: this.SquareMatrix and s are of the same width and height
         //POST: this.SquareMatrix - s
      }
      void Copy(SquareMatrix s){
         //PRE: s is an empty matrix
         //POST: s is a ixi matrix identical to this.SquareMatrix

      }

    };

So what I basically did is create a 2d array outside of the constructor and allocated memory within the constructor. Then, I tried to delete the pointer in the destructor, but it still gives me an error. Here's my main method:

#include <iostream>
#include "SquareMatrix.h"
using namespace std;

int main(){

  int size;
  int val;
  cout << "Enter the width and height of the square matrix: ";
  cin >> size;

  SquareMatrix<int> sq1(size);
  SquareMatrix<int> sq2(size);

  return 0;
}

Thanks!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
user6627083
  • 33
  • 1
  • 4
  • Why the C tag when this is clearly C++? – GhostCat Aug 31 '16 at 04:06
  • 2
    I'm not getting that error here: http://codepad.org/VjuVRA9v. Is there more code you haven't provided? – John Aug 31 '16 at 04:15
  • 2
    You are not adhering to the [rule of 3](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). You are passing `SquareMatrix` objects by value, and to do that, you need to properly implement the requisite copy operations. – PaulMcKenzie Aug 31 '16 at 04:16
  • @Trey - `sq1.Add(sq2);` That should make things go haywire. – PaulMcKenzie Aug 31 '16 at 04:20
  • You probably want to pass `SquareMatrix` parameters by const reference to avoid copying the matrices each time `Subtract` and `Copy` is called, otherwise you'll need to implement copying (the rule of 3 that @PaulMcKenzie mentioned above). – szx Aug 31 '16 at 05:20

1 Answers1

1

Because all your matrix operators take their parameter "by value" and you don't have a "copy constructor".

The one that causes problems at destruction is the one (supposedly copy) passed as parameter.

How about you declare your operations in terms on (const SquareMatrix& rhs)? Like

  void Add(const SquareMatrix& s){
     //PRE: this.SquareMatrix and s are of the same width and height
     //POST: this.SquareMatrix + s
    if(s.size==this->size) {
      for(int i=0; i<this->size; i++) {
        for(int j=0; j<this->size; j++) {
          this->sq_matrix[i][j]+=s.sq_matrix[i][j];
        }
      }
    }
  }

being called as

SquareMatrix<int> m1(3), m2(3);
m1.Add(m2);
Adrian Colomitchi
  • 3,974
  • 1
  • 14
  • 23
  • Thanks. I've never dealt with copy constructors before. So in the main method should i do something like SquareMatrix sq1(size); SquareMatrix sq2(size); sq1.Add(&sq2); ? – user6627083 Aug 31 '16 at 05:40
  • @user6627083 - see updated answer. Oh, man, you have serious reading ahead of you (if you don't know the syntax for 'parameter by reference'). Better get that reading started, some 'panta rei' just can't wait to stick his downvotes in the neck of the beginners ;) – Adrian Colomitchi Aug 31 '16 at 05:50