Транспонирование матрицы с динамическим выделением памяти

Пишу прогу по транспонированию матрицы. После написания алгоритма, решил также выделить память динамически. Сделал. Но чета ломается прога в случае, когда num_of_rows не равно num_of_cols. И есть подозрение, что оператор присвоения тоже написан неверно, так как впервые делал это для двумерного массива. Без выделения памяти все работает! Укажите, пожалуйста, на ошибку.

Код с выделенной памятью:

#include <iostream>
using namespace std;

class Transpose{
    int cols, rows, **data;
public:
    Transpose(int arows, int acols){
        cols = acols;
        rows = arows;
        
        data = new int *[rows];
        for (int i = 0; i < rows; i++)
        data[i] = new int[cols];
        }
        
    ~Transpose(){
        for (int i = 0; i < rows; i++) {
            delete[] data[i];
        }
        delete[] data;
        }
        
        void scan(){
        cout<<"Vvedite "<<cols * rows<<" cifri\n";

        for(int i=0; i< rows; i++){
            for(int j=0; j< cols; j++){
            cin>>data[i][j];}
        }
        cout << endl;
    }
        
        void display()
        {
            for(int i=0; i< rows; i++){
                for(int j=0; j< cols; j++){
                    cout<<data[i][j]<<" ";}
                    cout << "\n";
            }
            cout<< endl;
        }
        
        void print()
        {
            for(int i=0; i< cols; i++){
                for(int j=0; j< rows; j++){
                cout<<data[i][j]<<" ";}
                cout << "\n";
            }
            cout << endl;
        }

    Transpose(const Transpose &ob)
{
    rows=ob.rows;
    cols=ob.cols;
    
    data = new int *[rows];
    for (int i = 0; i < rows; i++)
    data[i] = new int[cols];
    
    for(int i=0;i<rows;i++){
        for(int j=0;j<cols;j++){
        data[i][j]=ob.data[i][j];
        }
    }
}

    Transpose transpose(){
        Transpose temp(rows,cols);
                
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                temp.data[j][i] = data[i][j];
            }
        }
        return temp;}
        
    Transpose& operator=(const Transpose& ob)
    {
            
        if (this == &ob)
        return *this;
            
        if (data) delete[] data;
            
        rows=ob.rows;
        cols=ob.cols;
            
        data = new int *[rows];
        for (int i = 0; i < rows; i++)
        data[i] = new int[cols];
        
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
            data[i][j]=ob.data[i][j];
            }
        }
        return *this;
    }
};

int main(){
    int num_of_cols, num_of_rows;
    cout <<"input the num of cols and rows"<<endl;
    cin >> num_of_rows >> num_of_cols;
    
    Transpose ob1(num_of_rows, num_of_cols), ob2(num_of_cols, num_of_rows);     
    ob1.scan(); ob1.display();
    ob2 = ob1.transpose();
    ob2.print();
}

Код без выделения:

#include <iostream>
using namespace std;

class Transpose{
    int cols, rows, data[10][10];
public:
    Transpose(int arows, int acols){
        cols = acols;
        rows = arows;
        
        }
        
        void scan(){
        cout<<"Vvedite "<<cols * rows<<" cifri\n";

        for(int i=0; i< rows; i++){
            for(int j=0; j< cols; j++){
            cin>>data[i][j];}
        }
        cout << endl;
    }
        
        void display()
        {
            for(int i=0; i< rows; i++){
                for(int j=0; j< cols; j++){
                    cout<<data[i][j]<<" ";}
                    cout << "\n";
            }
            cout<< endl;
        }
        
        void print()
        {
            for(int i=0; i< cols; i++){
                for(int j=0; j< rows; j++){
                cout<<data[i][j]<<" ";}
                cout << "\n";
            }
            cout << endl;
        }
    
    Transpose transpose(){
        Transpose temp(rows,cols);
                
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                temp.data[j][i] = data[i][j];
            }
        }
        return temp;}
};

int main(){
    int num_of_cols, num_of_rows;
    cout <<"input the num of cols and rows"<<endl;
    cin >> num_of_rows >> num_of_cols;
    
    Transpose ob1(num_of_rows, num_of_cols), ob2(num_of_cols, num_of_rows);     
    ob1.scan(); ob1.display();
    ob2 = ob1.transpose();
    ob2.print();
}

Ответы (1 шт):

Автор решения: Harry

Вы выделяете точное количество памяти. А потом при транспонировании

Transpose transpose(){
    Transpose temp(rows,cols);
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            temp.data[j][i] = data[i][j];
        }

создаете такую же матрицу, в которой rows строк по cols элементов, но пишете в нее cols строк по rows элементов, неизбежно выходя за рамки выделенной памяти при rows != cols!

Да и, кстати, у вас оператор присваивания написан не совсем верно, с утечкой памяти, а конструктора копирования и вовсе нет, так что даже после того как вы исправите transpose(), все источники неприятностей не иссякнут...

Update

Вот как бы это делал я...

#include <iostream>
#include <iomanip>

using namespace std;

class Matrix
{
    size_t rows, cols;
    int **data;
    void swap(Matrix&M)
    {
        std::swap(data,M.data);
        std::swap(rows,M.rows);
        std::swap(cols,M.cols);
    }
public:
    Matrix(size_t rows, size_t cols):rows(rows),cols(cols)
    {
        data = new int *[rows];
        for(size_t i = 0; i < rows; i++)
            data[i] = new int[cols];
    }
    ~Matrix()
    {
        for (size_t i = 0; i < rows; i++)
            delete[] data[i];
        delete[] data;
    }

    Matrix(const Matrix&M):Matrix(M.rows,M.cols)
    {
        for(size_t i = 0; i < rows; i++)
        for(size_t j = 0; j < cols; j++)
            data[i][j] = M.data[i][j];
    }

    Matrix& operator = (const Matrix& M)
    {
        Matrix tmp(M);
        swap(tmp);
        return *this;
    }

    friend ostream& operator<<(ostream&os, const Matrix& M);
    friend istream& operator>>(istream&is,       Matrix& M);

    Matrix transpose()
    {
        Matrix temp(cols,rows);
        for(size_t i = 0; i < rows; i++)
            for(size_t j = 0; j < cols; j++)
                temp.data[j][i] = data[i][j];
        return temp;
    }
        
};


ostream& operator<<(ostream&os, const Matrix& M)
{
    for(size_t i = 0; i < M.rows; i++)
    {
        for(size_t j = 0; j < M.cols; j++)
        {
            os << M.data[i][j]<< " ";
        }
        os << "\n";
    }
    return os;
}

istream& operator>>(istream&is, Matrix& M)
{
    for(size_t i = 0; i < M.rows; i++)
    {
        for(size_t j = 0; j < M.cols; j++)
        {
            cout << "Matrix[" << i << "][" << j << "] = ";
            is >> M.data[i][j];
        }
    }
    return is;
}

int main()
{
    int num_of_cols, num_of_rows;
    cout <<"input the num of cols and rows"<<endl;
    cin >> num_of_rows >> num_of_cols;
    
    Matrix ob1(num_of_rows, num_of_cols);
    cin >> ob1;
    cout << "\n\n" << ob1 << "\n\n";

    Matrix ob2 = ob1.transpose();

    cout << ob2 << "\n\n";
}
→ Ссылка