Matrix size

Below, when I run this with a1(20,5), the program displays what is expected, but it also gives a "Segmentation fault (core dumped)" message. However a1(20,4) works just fine - no errors. Why would that be the case?

#include <iostream>
using std::cout;
using std::endl;

class matrix
{
public:
int number_of_rows;
int number_of_columns;

// Constructor
matrix(int number_of_rows, int number_of_columns)
{
for (int row=0; row < number_of_rows; row++)
{
for (int column=0; column < number_of_columns; column++)
{
matrix_current[row][column] = 0;
cout << matrix_current[row][column] << "\t";
}
cout << endl;
}
}

// Display Matrix
void display()
{
for (int row=0; row < number_of_rows; row++)
for (int column=0; column < number_of_columns; column++)
cout << matrix_current[row][column] << "\t";
cout << endl;
}

private:
float matrix_current[0][0];
};

int main()
{
matrix a1(20,5);
}
float matrix_current[0][0];
This is a 2D array having zero rows and zero columns; it has no accessible elements at all.

Any time you do an assignment statement such as this,
 
    matrix_current[row][column] = 0;

then you are updating some memory outside the array. This must be the case, regardless of the values of row and column, since the array has no elements at all.

Modifying memory which does not belong to your program will cause a fault. The only surprise is that the program does not crash even sooner.
Chervil,

Thank you! Actually, I had wanted *not* to specify the sizes. I had wanted to have something like this:

private:
float* matrix_current[ ][ ];

However, the compiler won't allow me, and instead throws this error:

matrix.cpp:38:31: error: declaration of ‘matrix_current’ as multidimensional array must have bounds for all dimensions except the first.

This is a handicap. Why cannot I just declare the 2D array to have variable size? I don't want to use vector of vectors as they can be unwieldy to manage (or not?)

Here is some code borrowed from another thread, it should give an idea of how to dynamically allocate a 2D array
1
2
3
4
5
6
7
8
int ** create_array(int rows, int cols)
{
    int ** arr = new int * [rows];
    for (int i=0; i<rows; i++)
        arr[i] = new int [cols];

    return arr;
}
Vector of vectors are easy to manage imo. I honestly prefer vectors over arrays any day. Anyways arrays are meant to be known at compile time. You could do something like this though if you want to be a rebel.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int** create_array( int &rows , int &columns )
{
    int **arr = new int*[ rows ];
    for( auto i = 0; i < rows; ++i )
    {
         arr[ i ] = new int[ columns ];
    }
    
    return( arr );
}

int main()
{
    create_array( 2 , 3 );
}


Don't forget to delete it when you are done with it though.
Thank you Chervil and giblit! A more basic question to wind up this thread if you don't mind. The * makes perfect sense, in that it refers to a pointer, that would contain the address of the variable it points to. I am somewhat not clear with the concept of pointer-to-pointer (**). I am guessing a pointer-to-pointer would contain the address of an address? Isn't the address of an address, just the address itself?

1
2
3
   int variable = 10;
   int *pointer = &variable;
   int *ptr_to_ptr = &(pointer);


No it points to the address of the pointer which is different from the address of what it is pointing to.
http://www.cplusplus.com/doc/tutorial/pointers/
Towards the bottom it explains pointers-to-pointers better than I can explain.
Thanks. I guess what I was incorrectly assuming that pointers don't occupy memory themselves (and therefore, pointers by themselves would not "reside" anywhere i.e. at another address). But from the link you sent, it appears that pointers do indeed occupy memory and the address value stored in them can be in turn pointed to again by another pointer. Makes sense!
Topic archived. No new replies allowed.