Calvin Miller
Calvin Miller

Reputation: 25

Segmentation fault while passing multidimensional arrays, c++

I'm pretty new to coding in c++ so I apologize if this question has a very apparent simple answer. I'm trying to create a matrix of random numbers from -1 to 1. These are the two functions I am using:

#include <iostream>
#include "matrix_fill_random.cpp"
using namespace std;

int main(int argc, int argv[]){

int n1, n2, n3;

if (argc != 4) {
    cerr << "This program requires 3 argument!" <<endl;
    return 1;
}
else{
    n1 = argv[1];
    n2 = argv[2];
    n3 = argv[3];

    double** a;

    matrix_fill_random(n1, n2, a);

    return 0;
}
}

and

#include <iostream>
using namespace std;

int matrix_fill_random(int n1, int n2, double** a){
for (int i=0; i<n1; i++){
    for (int j=0; j<n2; j++){
        double num = rand() % 2 - 1;
        a[i][j]=num;
    }
}
return 0;
}

Ultimately I'm trying to create two matrices and then multiply them together so n1, n2, and n3 represent the rows and columns of two matrices, but that isn't all too important right now. I think the error might be in how I declare my variables or pass them to other functions but I'm not entirely sure.

I feel like if I can understand the principle of creating one of the matrices then that would translate to the other functions I need to use.

Upvotes: 1

Views: 939

Answers (4)

Drew Chapin
Drew Chapin

Reputation: 7989

You need to allocate memory to a before passing it to matrix_fill_random().

double** a = new double[n1];

Since you're using C++ though, you should consider using a vector or other template container.

Upvotes: 0

David G
David G

Reputation: 96790

double** a;

You haven't allocated memory for the pointer, so you're getting Undefined Behavior each time you dereference it using operator [].

You should allocate a once before passing it through the function...

double** a = new double*[n1];

and once more inside the for loop of the function:

for (int i = 0; i < n1; i++)
{
    a[i] = new double[n2];
    for (int j = 0; j < n2; j++)
    {
        double num = rand() % 2 - 1;
        a[i][j] = num;
    }
}

But don't forget to delete[] the pointer once you're done using it. You should delete the other pointers allocated inside the for loop as well.

Of course, this can all be avoided by using std::vector. Here is your program fitted with the Standard Library:

std::vector<std::vector<double>> a(n1, std::vector<double>(n2));

int matrix_fill_random(std::vector<std::vector<double>> a)
{
    for (int i = 0; i < a.size(); ++i)
    {
        for (int j = 0; j < a[i].size(); ++j)
        {
            double num = rand() % 2 - 1;
            a[i][j] = num;
        }
    }
    return 0;
}

Upvotes: 1

LihO
LihO

Reputation: 42085

double** a;
matrix_fill_random(n1, n2, a);

passes uninitialized pointer a to the function, which tries to initialize elements of two-dimensional array:

a[i][j]=num;

which invokes an undefined behavior. The simplest solution would be to allocate a single block of memory that will be big enough to hold the matrix:

double* a = new double[rows * cols];
matrix_fill_random(n1, n2, a);
delete[] a;
a = NULL;

...

// accessing element a[i][j] in the function's body:
a[i*cols + j] = num;

but most reasonable solution would be using std::vector instead of C-style arrays.

Upvotes: 0

Vallabh Patade
Vallabh Patade

Reputation: 5110

Allocate the memory for a. You haven't allocate the memory for a. Chane the statement double** a; to

  double** a = new double[n1];

and change the loop as follows

  for (int i = 0; i < n1; i++)
  {
    //Every row will be of size = number of columns.
    a[i] = new double[n2];
    for (int j = 0; j < n2; j++)
    {
        double num = rand() % 2 - 1;
        a[i][j] = num;
    }
  } 

Upvotes: 1

Related Questions