2013-10-01 4 views
0

AoA, Вот код умножения двух матриц, который отлично работает под матрицами 3x3, но дает ошибку при превышении строки или столбца 3x3, например, на 3x4 и 4x3. дает ошибку «ошибку сегментации»Ошибка сегментации в Linux C++, но код работает в окнах

#include <unistd.h> 
#include <pthread.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <iostream> 

using namespace std; 

struct matrix 
{ 
    int** mat; 
    int row; 
    int col; 
    matrix(int m,int n) 
    { 
     row = m; 
     col = n; 
     mat = new int*[row]; 
     for(int i=0;i<row;i++) 
     { 
      mat[i] = new int[col]; 
      for(int k=0;k<col;k++) 
      { 
       mat[i][k] = 0; 
      } 
     } 
    } 
}; 

matrix* MultiplyMat(matrix* matA,matrix* matB) 
{ 
    matrix* tMat = new matrix(matA->row,matB->col); 
    if(matA->row == matB->col) 
    { 
     for(int i=0; i<matA->row; i++) 
     { 
      for(int j=0;j<matB->col;j++) 
      { 
       for(int m=0;m<matB->col;m++) 
       { 
        tMat->mat[j][i] += matA->mat[j][m] * matB->mat[m][i]; 
       } 
      } 
     } 
    } 

    return tMat; 
} 

void PrintMatrix(matrix* tMat) 
{ 
    cout<<"Print: Matrix\n\n"; 
    for(int i=0;tMat->row;i++) 
    { 
     for(int j=0;j<tMat->col;j++) 
     { 
      cout<<" "<<tMat->mat[i][j]; 

     } 
     cout<<"\n"; 
    } 

} 

int main() 
{ 
    matrix matB(3,4); 
    matrix matA(4,3); 

    matA.mat[0][0] = 2; 
    matA.mat[0][1] = 1; 
    matA.mat[0][2] = 4; 
    matA.mat[1][0] = 6; 
    matA.mat[1][1] = 5; 
    matA.mat[1][2] = 9; 
    matA.mat[2][0] = 8; 
    matA.mat[2][1] = 7; 
    matA.mat[2][2] = 11; 
    matA.mat[3][0] = 5; 
    matA.mat[3][1] = 5; 
    matA.mat[3][2] = 9; 

    matB.mat[0][0] = 2; 
    matB.mat[0][1] = 1; 
    matB.mat[0][2] = 4; 
    matB.mat[0][3] = 3; 
    matB.mat[1][0] = 6; 
    matB.mat[1][1] = 5; 
    matB.mat[1][2] = 9; 
    matB.mat[1][3] = 12; 
    matB.mat[2][0] = 8; 
    matB.mat[2][1] = 7; 
    matB.mat[2][2] = 11; 
    matB.mat[2][3] = 13; 

    matrix* matC = MultiplyMat(&matA,&matB); 
    PrintMatrix(matC); 


    return 0; 
} 

Я просто пытаюсь Multiplay две матрицы, компилятор г ++ дает ошибку «ошибку сегментации» Я попробовал метод (нашел на этом сайте) отладки, но не удалось удалить ошибку!

Любая помощь?

+1

Вы выделить пространство для 'tMat' но ничего для его строк/столбцов БД-указатель члена' mat'. То, что вы делаете 'malloc(), что-либо на C++, вне меня, но это специально ведет вас прямо к ** неопределенному поведению **. – WhozCraig

+0

Скорее всего, программа, а не компилятор, дает вам segfault? Пробовал отладчик? –

+1

Вы также заполняете строку 3 матрицы, которая имеет только строки 0, 1, 2. – zch

ответ

2

Эта линия является неправильным:

matrix* tMat = (matrix*)malloc(sizeof(matrix)); 

Я не совсем уверен, что вы ожидаете это сделать, но это, вероятно, не делает этого ... На самом деле, это не делает много вообще, кроме создания блока памяти, достаточно большого для структуры matrix. Он заполнен каким-то случайным мусором (который может быть или не быть нулями).

Вы затем пойти дальше и использовать его:

   tMat->mat[j][i] += matA->mat[j][m] * matB->mat[m][i]; 

, который, скорее всего, означает, что вы либо доступ к NULL или некоторый случайный адрес мусора, который не является действительным. Затем вернуть указатель на него, который не освобожденного здесь:

matrix* matC = MultiplyMat(&matA,&matB); 
PrintMatrix(matC); 

return 0; 

Вы, наверное, хотите что-то вроде:

matrix* tMat = new matrix(matB->col, matA->row); 

Но вы бы гораздо лучше создать matrix operator*(const matrix& a, const matrix& b), так что вы не верните указатель. Накладные расходы будут довольно маленькими.

+0

К сожалению, я виноват, я изменил строку только для отладки, я отредактировал свой ответ, вы можете увидеть полный код выше, он также дает ошибка с вышеупомянутым отредактированным кодом вопроса –

+0

+1 Помимо этого класс 'matrix' не очищает свою выделенную память, что должно быть сделано в сочетании с реализацией правильного [правила трех] (http: //en.wikipedia .org/wiki/Rule_of_three_ (C% 2B% 2B_programming)) семантика так или иначе (умные указатели в идеале), и * оба * из них должны быть выполнены до реализации функциональности с возвратом значений.Короче говоря, этот код только на полпути, где это должно быть сделано правильно. – WhozCraig

+0

Вы случайно не программист fortran? Вы заполняете свою матрицу неправильным способом [или определяете неправильный путь], так как 'matA [3] [0] = 5;' идет не так в соответствии с gdb - я действительно не проверял такие вещи, когда писал свой ответ ... –

0

В вашей матрице имеется конструктор, но он не вызывается при распределении памяти с использованием malloc(). Вы явно хотите использовать

matrix* tMat = new matrix(m, n); 

с подходящим аргументом m и n. Ну, на самом деле, вы скорее хотите использовать

std::unique_ptr<matrix> tMat(new matrix(m, n)); 

... но это просто связано с следующей проблемой вы получите, как только вы получите мимо вашей ошибки сегментации: вам также необходимо очистить ресурсы. Кроме того, не совсем то, что вы действительно хотите, хотя, потому что вы действительно хотите что-то вроде этого:

matrix MultiplyMat(matrix const& a, matrix const& b) { 
    // ... 
    matrix result(m, n); 
    // ... 
    return result; 
} 
+0

это давая ошибку! unique_ptr не найден в области –

+0

@SaadAbdullah: конечно. Вам нужно будет включить '' для использования 'std :: unique_ptr '. ... и вам понадобится компилятор C++ 11 (если вы компилируете C++ 03, вы можете использовать 'std :: auto_ptr ', этот шаблон шаблона также объявляется в ''). –

+0

нашел! :) хотя я нашел ошибку! но +1 для unique_ptr –

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