-1

Two vectors are created and values are assigned to both the vectors and then the two vectors are multiplied with each other. (A matrix multiplication). Gives a segmentation fault error in the multiply function. Is it something to with trying to access an location out of the scope?

#include<iostream>
#include <vector>

using namespace std;

int n;
vector <int> mat1Rows;
vector <int> mat2Rows;
vector <int> multRows;
vector <vector<int> > mat1;
vector <vector<int> > mat2;
vector <vector<int> > multMat;

void assignValues(int num){

        for(int i = 0; i < num; i++){
                for(int j = 0; j < num; j++){
                        mat1Rows.push_back(j);
                        mat2Rows.push_back(j);
                }
                mat1.push_back(mat1Rows);
                mat2.push_back(mat2Rows);

        mat1Rows.clear();
        mat2Rows.clear();
        }
}

void multiply(int n){

        for(int i = 0; i < n; ++i){
                for(int j = 0; j < n; ++j){
                        for(int k = 0; k < n; ++k){

                multMat[i][j] += mat1[i][k] * mat2[k][j];
                        }
                }
    }
}

void displayMult(int n){

    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){

            cout << multMat[i][j] << " " ;
        }

        cout << endl;
    }

}

int main(){

    cout << "Enter the size of the matrix: ";
    cin >> n;

    assignValues(n);

    multiply(n);

    displayMult(n);

    return 0;   
}
Rashmika97
  • 37
  • 9
  • 1
    Your program does not compile. Please, add required includes. – Piotr Siupa Apr 18 '19 at 07:21
  • "Is it something to with trying to access an location out of the scope?" - this is pretty much what segmentation fault means. The easiest way to find it is to step through your program line by line with debugger. – Piotr Siupa Apr 18 '19 at 07:23
  • @NO_NAME Added the includes. – Rashmika97 Apr 18 '19 at 07:24
  • 1
    `multMat` vector is empty at the moment when you try to get a reference to its element with `multMat[i][j]`. – vahancho Apr 18 '19 at 07:26
  • 1
    @Rashmika97 Use `vector::at()` instead of `[ ]` to access the items in the vector. You will then see that the program will throw a `std::out_of_range` exception instead of just a seg fault when it encounters an `at()` call that is out of bounds. – PaulMcKenzie Apr 18 '19 at 07:37

1 Answers1

1
 multMat[i][j] += mat1[i][k] * mat2[k][j];

There is no memory inside multMat as you didn't reserve any memory for the elements. You need to tell vector to allocate memory. You can do that with resize, to allocate the memory for the elements and change the size of the vector..

 void multiply(int n) {
       multMat.resize(n);
       for (auto&& i : multMat) {
             i.resize(n);
       }
       ... rest of the code ...
  }

The std::vector::operator[] does not perform bounds checking. So if you specify an index outside of allowed bounds and try to assign something to returned reference, undefined behavior happens. Use std::vector::at() to be always sure your indices are valid.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • 1
    Btw, `reserve()` does not change the size of the vector. – vahancho Apr 18 '19 at 07:28
  • 1
    Shouldn't it be `resize()` instead of `reserve()`? `reserve()` would prevent the segmentation fault but accessing fields outside of `size()` of the vector still smells like an undefined behavior to me. – Piotr Siupa Apr 18 '19 at 07:28
  • Would it be appropriate to reserve memory since this is a dynamic allocation? – Rashmika97 Apr 18 '19 at 07:30
  • The `operator[]` does not perform any allocation. It does not perform any checking. It is undefined behavior to use it outside of bounds. – KamilCuk Apr 18 '19 at 07:31
  • Yeah, I agree that in the case of vector of some fundamental type it doesn't do much a difference. Better to know when to use `resize()` and when `reserve()`, though. It could cause some pretty weird error in vector of objects with constructor and destructor. Beside that, an attempt to use `push_back` would override the data if only `resize()` if only `resize()` was called. – Piotr Siupa Apr 18 '19 at 07:37
  • `std::vector::get`? I cannot find it in the reference page: http://www.cplusplus.com/reference/vector/vector/ – Piotr Siupa Apr 18 '19 at 07:42