2015-04-23 4 views
1

Я новый программист на C++. Я хочу создать класс Matrix в C++, используя динамическое программирование. У меня возникла проблема с конструктором копирования. Когда я вызываю оператор +, чтобы использовать его для добавления матрицы, конструктор копирования генерирует исключение bad_alloc-Exception. Проблема возникает в copy-constructor, когда я пытаюсь создать новую динамическую память, где могу копировать свои данные: matrix = new int [size]; Я не понимаю, почему. Вот весь код: (только CPP-файл)Копировать конструктор бросает std :: bad_alloc, когда он называется

#include <iostream> 
#include "Matrix.hpp" 

Matrix::Matrix(int m, int n){ 
    mat_row=m; 
    mat_col=n; 
    matrix = new int[mat_row*mat_col]; 
    //initialization 
    for(int i=0;i<mat_row*mat_col;i++){ 
     matrix[i]=0; 
    } 
} 

//copy-Constructor 
    Matrix::Matrix(const Matrix& mat){ 
     int size=mat_row*mat_col; 
     matrix= new int [size]; 
     for(int i=0;i<size;i++){ 
      matrix[i]=mat.matrix[i]; 
     } 
    } 

    Matrix::~Matrix(){ 
     if(matrix){ 
      delete [] matrix; 
     } 
    } 


    //assigment operator 
    Matrix& Matrix::operator=(const Matrix& mat){ 
     std::cout<<"assignment-operator is used"<<std::endl; 
     if(this!=&mat){ 
      int size=mat_row*mat_col; 
      for(int i=0;i<size;i++){ 
      matrix[i]=mat.matrix[i]; 
      } 
     } 
     return *this; 
    } 

    void Matrix::set(int m, int n, double value){ 
     if(matrix){ 
      matrix[m*mat_col+n]=value; 
     } 
    } 

    double Matrix::get(int m, int n){ 
     return matrix[m*mat_col+n]; 
    } 


Matrix Matrix::operator+(Matrix mat){ 
/* 
    Matrix resultMatrix(mat_row, mat_col); 
    for(int i=0;i<mat_row;i++){ 
     for(int j=0;j<mat_col;j++){ 
      resultMatrix->set(i,j,this->get(i,j)+mat.get(i,j)); 
     } 
    } 
    return *this; 
    */ 
    } 



    int main(){ 
     Matrix mat1(3,3); 
     mat1.set(0,0,11); 
     mat1.set(1,1,22); 
     mat1.set(2,2,33); 
     mat1.print(); 
     std::cout<<std::endl; 

     Matrix mat2(3,3); 
     mat2=mat1; 
     mat2.print(); 
     std::cout<<std::endl; 
     mat2.set(0,1,55); 
     mat2.set(1,1,110); 
     mat2.set(2,2,220); 
     mat2.print(); 

     mat1+mat2; //the problem occurs when this row will be executed 
    } 
+0

Прототип оператора + должен быть «Матричным оператором + (const Матрица & левая, const Матрица и право)' – mpromonet

+0

Нет, в этом случае этого не должно быть. В этом случае это должен быть «Матричный оператор + (const Matrix & mat)», потому что он является функцией-членом. Если бы OP включил функцию друга для оператора +, тогда вы подпишитесь правильно. – hvanbrug

+0

Почему 'новый'? Вы должны использовать шаблон и сохранять значения прямо в объекте «Матрица». – doug65536

ответ

1

Первое, что я заметил, что в вашей копии конструктора mat_row и mat_col не инициализируются. Они должны быть установлены из значений, находящихся в объекте, который вы копируете, прежде чем умножать их вместе, чтобы сделать размер. Если вы этого не сделаете, то существующие значения не определены и, вероятно, очень большие значения, что приведет к сбою нового.

//copy-Constructor 
    Matrix::Matrix(const Matrix& mat){ 
     mat_row = mat.mat_row; 
     mat_col = mat.mat_col; 
     int size=mat_row*mat_col; 
     matrix= new int [size]; 
     for(int i=0;i<size;i++){ 
      matrix[i]=mat.matrix[i]; 
     } 
    } 

Похоже, что у вас есть одна и та же проблема в вашем операторе =().

В коде, где указывается, что ваша проблема возникает, у вас нет lvalue. У вас есть mat1+mat2;, поэтому результат этого добавления не используется.

Кроме того, ваш оператор +() должен принимать const ref в матрицу, и это ваша фактическая проблема. Передача по значению, как вы сейчас, приведет к созданию временной копии, созданной с помощью конструктора копирования.

+0

Я инициализировал их, но все еще искал проблему. Возникает проблема дефекта сегментации. Когда выполняется mat1 + mat2, будет вызван coy-constructor. Затем копия-конструктор попытается распределить новую часть памяти динамически. В этот момент возникает ошибка сегментации – amitakCs

+0

Вы получаете исключение из нового при сбое распределения. Обычно это говорит о том, что размер распределения не подходит. Я просто запустил ваш код и, похоже, работает до тех пор, пока вы исправляете, как я предложил как конструктору копирования, так и оператору присваивания, как я предложил в ответ. – hvanbrug

+0

большое спасибо. он работает сейчас ::: :)))). Я передал матрицу постоянной ссылкой, как вы сказали. Затем я изменил метод get (i, j) на постоянный метод. Теперь это работает. Но почему сбой не прошел, когда мы проходим по значению. Почему копия, созданная конструктором-копией, вызывает ошибку сегментации. – amitakCs

Смежные вопросы