Hello. I am new to programming and am just starting to learn a lot (although I have some training, it is funny to consider it at least serious). Seeking classes, trying to build something to work with matrices. The implementation code is not important, it is important that I get the error: http://prntscr.com/e6y5on The key question is how to fix it.

Matrix.h:

#ifndef MATRIX_H #define MATRIX_H class Matrix { private: int m_rows = 1; int m_cols = 1; int** m_matrix = new int* [m_rows]; public: Matrix(int rows, int cols); void SetSize(int rows, int cols); void Create(); int rows(); int cols(); ~Matrix(); }; #endif 

Matrix.cpp:

 #include <iostream> #include <math.h> #include "matrix.h" using namespace std; Matrix::Matrix(int rows, int cols) { SetSize(rows, cols); Create(); } void Matrix::SetSize(int rows, int cols) { m_rows = rows; m_cols = cols; } void Matrix::Create() { for (int i = 0; i < m_rows; i++) m_matrix[i] = new int[m_cols]; cout << "Matrix created with " << m_rows << " rows and " << m_cols << " cols." << endl; } int Matrix::rows() { return m_rows; } int Matrix::cols() { return m_cols; } Matrix::~Matrix() { for (int i = 0; i < m_rows; i++) delete[] m_matrix[i]; delete[] m_matrix; cout << "Matrix deleted" << endl; } 

main.cpp:

 int main() { Matrix m(2,2); return 0; } 

When step-by-step checking in Visual Studio, the program is poured upon the removal of the external pointer delete [] m_matrix; Actually, please help =)

  • one
    It would be better if you added the text of the error to the question not as a link - aleks.andr
  • I'll keep it on mind. New to stackoverflow) - Ari

5 answers 5

Let's figure it out.

 int m_rows = 1; int m_cols = 1; int** m_matrix = new int* [m_rows]; 

So, you immediately allocate memory and create a 1x1 matrix. Since in the constructor

 Matrix::Matrix(int rows, int cols) 

you do not have member initialization, they are initialized by default with this matrix.
But what do you do next? You rewrite m_rows and m_cols , and in the already allocated array for ONE pointer write them m_rows , i.e. in this particular case, two.

Here you have the source of your troubles. Your attempt to rectify the situation is simply an attempt not to notice the error. It cannot lead to anything good. The next time you write them there with a dozen, and still clog the memory more thoroughly, that's all.

Here's how your matrix should look good:

 class Matrix { private: int m_rows; int m_cols; int** m_matrix; public: Matrix(int rows, int cols); void SetSize(int rows, int cols); void Create(); int rows(); int cols(); ~Matrix(); }; Matrix::Matrix(int rows, int cols) :m_rows(rows),m_cols(cols) { m_matrix = new int*[m_rows]; for (int i = 0; i < m_rows; i++) m_matrix[i] = new int[m_cols]; cout << "Matrix created with " << m_rows << " rows and " << m_cols << " cols." << endl; } Matrix::~Matrix() { for (int i = 0; i < m_rows; i++) delete[] m_matrix[i]; delete[] m_matrix; cout << "Matrix deleted" << endl; } 
  • Thank you very much =) - Ari
  • @Ari if you like the answer. Vote for it (arrows on the left). It's free. - αλεχολυτ

Apparently, you create an int ** m_matrix of one size, and then pass parameter 2 and think that there are 2 lines. Apparently you'd better create a dynamic array in the Create method:

 void Matrix::Create(){ m_matrix = new int*[m_rows]; for (int i = 0; i < m_rows; i++) m_matrix[i] = new int[m_cols]; cout << "Matrix created with " <<m_rows<<" rows and "<<m_cols<<" cols."<< endl; } 

    The class has a call beyond the allocated memory. If you add the following two sentences to the constructor

     Matrix::Matrix(int rows, int cols) { std::cout << "m_rows = " << m_rows << std::endl; std::cout << "m_cols = " << m_cols << std::endl; SetSize(rows, cols); Create(); } 

    then when creating a class object, a message will be displayed on the console

     m_rows = 1 m_cols = 1 

    That means before. as the body of the constructor got control, the members of the class were initialized

     int m_rows = 1; int m_cols = 1; int** m_matrix = new int* [m_rows]; 

    as a result of which memory was allocated for an array of pointers from one pointer of type int * .

    However, in the Create function, since in the general case the value of m_rows, specified in the constructor, may differ from 1, then the output goes beyond the dynamically allocated array.

     void Matrix::Create() { for (int i = 0; i < m_rows; i++) m_matrix[i] = new int[m_cols]; cout << "Matrix created with " << m_rows << " rows and " << m_cols << " cols." << endl; } 

    There is no point in initializing the class members in the class definition instead of initializing them in the constructor.

    Keep in mind that you also need to define a copy constructor and a copy assignment operator, or define them as deleted.

    • Thanks very much =) - Ari
    • @Ari Not at all. Ask more. :) - Vlad from Moscow

    You incorrectly allocate memory. This line:

     int** m_matrix = new int*[m_rows]; 

    It is necessary to transfer from the header ( .h ) to the implementation of the Create() function:

     void Matrix::Create() { m_matrix = new int*[m_rows]; for (int i = 0; i < m_rows; i++) m_matrix[i] = new int[m_cols]; } 

    In the heading, leave only the pointer declaration:

     int** m_matrix; 

    Destructor returns to your original view:

     Matrix::~Matrix() { for (int i = 0; i < m_rows; i++) delete[] m_matrix[i]; delete[] m_matrix; } 
    • The competent organization of classes for me is still not an entirely clear topic, and therefore I continue to dig. Thank you) - Ari

    Found the answer to your own question. I don’t know if it’s a class or is it so correct, but deleting

     for (int i = 0; i < m_rows; i++) delete[] m_matrix[i]; 

    It turned out more than enough.

    • 2
      In this case there will be a memory leak - Unick
    • No, absolutely wrong. And leakage is minimal evil: you just disguised the mistake (see my answer). - Harry
    • Got it, thanks. - Ari