heyheythere
heyheythere

Reputation: 11

Why is my program crashing when I enter the values for a matrix?

I am entering the values for a matrix. It has now been modified to be a vector instead of an array thanks to a someone's help on fixing my code. However, the program now crashes after entering in the elements for Matrix B. Also, it's pretty strange but after entering in the number of columns for either matrix the program allows me to just keep entering in a few more values for the number of columns before prompting me to enter the elements of the matrix.

#include <iostream>
#include <vector>

using namespace std;

int main()
{   
    int x,y,i,j,m,n;
    vector<vector<int> > A;
    vector<vector<int> > B;
    vector<vector<int> > C;


    cout<<"Enter the number of rows for Matrix A: "<<endl;
    cin>>x;
    cout<<"Enter the number of rows for Matrix B: "<<endl;
    cin>>y;

     //dynamically resizeable array of dynamically resizeable arrays
    A.resize(x); // allocate storage for x dimension.
    for (i = 0; i < x; i++)
    {
    A[i].resize(y); // allocate storage for y dimension for this one x 
    for (j = 0; j < y; j++)
    {
        cin >> A[i][j];
    }
    cout << endl;
    }

    cout<<"\n\nEnter the elements of Matrix A: "<<endl;

    for(i=0;i<x;i++)
    {
        for(j=0;j<y;j++)
        {
            cin>>A[i][j];
        }
        cout<<endl;
    }

    cout<<"\n\nMatrix A :\n\n";

    for(i=0;i<x;i++)
    {
        for(j=0;j<y;j++)
        {
            cout<<"\t"<<A[i][j];
        }
        cout<<endl;
    }

    cout<<"********************************************************"<<endl;

    cout<<"Enter the number of rows for Matrix B: "<<endl;
    cin>>m;
    cout<<"Enter the number of columns for Matrix B: "<<endl;
    cin>>n;

    B.resize(m); // allocate storage for x dimension.
    for (i = 0; i < m; i++)
    {
    B[i].resize(n); // allocate storage for y dimension for this one x 
    for (j = 0; j < n; j++)
    {
        cin >> A[i][j];
    }
    cout << endl;
    }

    cout<<"\n\nEnter elements for Matrix B :\n\n";

    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>B[i][j];
        }
        cout<<endl;
    }


    cout<<"\n\nMatrix B :\n\n";

    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            cout<<"\t"<<B[i][j];
        }
        cout<<endl;
    }

    if(y==m)
    {

        for(i=0;i<x;i++)
        {
            for(j=0;j<n;j++)
            {
                C[i][j]=0;
                for(int k=0;k<m;k++)
                {
                    C[i][j]=C[i][j]+A[i][k]*B[k][j];
                }
            }
        }

        cout<<"*******************************************************"<<endl;

        cout<<"\n\nMultiplication of Matrix A and Matrix B: \n\n";

        for(i=0;i<x;i++)
        {
            for(j=0;j<n;j++)
            {
                cout<<"\t"<<C[i][j];
            }
            cout<<endl;
        }
    }
    else
    {
        cout<<"\n\nMultiplication is not possible"<<endl;;
    }

    system("pause");
    return 0;
}

Upvotes: 0

Views: 651

Answers (2)

PaulMcKenzie
PaulMcKenzie

Reputation: 35440

You say that the matrix is 20 x 1, but your arrays are 10 x 10. So your description is amiss.

But having said all that, you can still salvage your original code and not have it crash if you respected that the arrays are 10 x 10. You do this by simply writing the loop so that you don't exceed the arrays bounds, regardless of the input that was entered.

However you don't need to rewrite the loops themselves -- all you need to do is adjust the input so that it doesn't exceed the array's boundaries.

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
   const int MAXSIZE_X = 10;
   const int MAXSIZE_Y = 10;
   int A[MAXSIZE_X][MAXSIZE_Y], B[MAXSIZE_X][MAXSIZE_Y], C[MAXSIZE_X][MAXSIZE_Y];
   int x,y,i,j,m,n;
   int m_x, m_y; // used for inputting
   cout<<"Enter the number of rows for Matrix A: "<<endl;
   cin>> m_x;
   cout<<"Enter the number of rows for Matrix B: "<<endl;
   cin>> m_y;

   // set the minimum value for x and y here
   x = std::max(0, std::min(m_x, MAXSIZE_X));
   y = std::max(0, std::min(m_y, MAXSIZE_Y));

   //... Rest of the code to populate arrays
   //...
   cout<<"Enter the number of rows for Matrix B: "<<endl;
   cin>>m_x;
   cout<<"Enter the number of columns for Matrix B: "<<endl;
   cin>>m_y;

   // set the minimum allowed values for m and n
   m = std::max(0, std::min(m_x, MAXSIZE_X));
   n = std::max(0, std::min(m_y, MAXSIZE_Y));
   //...
   // Rest of the code goes here
   //...   
}

All I did was assign to x, y, m and n the minimum of whatever was entered and the actual dimension size of the array by using std::min. Also note how we don't allow negative values to be used by making sure that the value does not fall below 0 (by using std::max).

Once you do this, the loops will now not exceed the bounds of the arrays. The bottom line is that if you have a limit, you should throttle your arrays back so that you can never exceed the bounds.

Also note that if you actually did change the size to 20 x 1 (by changing the value of MAXSIZE_X and MAXSIZE_Y), none of the rest of the code will need to be changed.


Edit:

Now that you've changed your original question, my answer above no longer holds. Please refrain from doing that, as now others lose all context of the answer given and what you posted as a question.

Given that, the problem with your new code is this:

B.resize(m); // allocate storage for x dimension.
for (i = 0; i < m; i++)
{
    B[i].resize(n); // allocate storage for y dimension for this one x 
    for (j = 0; j < n; j++)
    {
        cin >> A[i][j];  // <-- This is supposed to be B, not A
    }
    cout << endl;
}

Also, you don't need to call vector::resize in a loop. You can resize the entire vector, both rows and columns in one call.

Example:

A.resize(x, vector<int>(y, 0));

That resizes the A matrix to x rows and y columns.

The other error is that you failed to resize the C or resulting matrix.

So to round things out, the code should look something like this:

//dynamically resizeable array of dynamically resizeable arrays
A.resize(x, vector<int>(y, 0));
for (i = 0; i < A.size(); i++)
{
    for (j = 0; j < A[i].size(); j++)
        cin >> A[i][j];
    cout << endl;
}

cout << "Enter the number of rows for Matrix B: " << endl;
cin >> m;
cout << "Enter the number of columns for Matrix B: " << endl;
cin >> n;

B.resize(m, vector<int>(n, 0)); // allocate storage for x dimension.
for (i = 0; i < m; i++)
{
    for (j = 0; j < n; j++)
        cin >> B[i][j];
    cout << endl;
}

// resize the resultant matrix accordingly
C.resize(x, vector<int>(n, 0));

I removed all of the fluff that just outputs what you inputted, as that is not important in understanding what really needs to be done.

In addition to this, a std::vector knows its size by using the vector::size() function. You should no longer need to carry around variables such as x, y, etc. to denote the number of items. Using extraneous variables that supposedly hold the vector's dimensions could lead to something going wrong somewhere down the road.

Upvotes: 1

user4581301
user4581301

Reputation: 33932

a 20x1 matrix

int A[10][10]

Going to have a wee bit of difficulty getting 20 elements in an array with a maximum size of 10.

Try:

cout<<"Enter the number of rows for Matrix A: "<<endl;
cin>>x;
cout<<"Enter the number of rows for Matrix B: "<<endl;
cin>>y;

cout << "\n\nEnter the elements of Matrix A: " << endl;

int ** A;  // raw pointer. Not a good idea.
A = new int*[x]; // allocate storage for x dimension.

for (i = 0; i < x; i++)
{
    A[i] = new int[y]; // allocate storage for y dimension for this one x
    for (j = 0; j < y; j++)
    {
        cin >> A[i][j];
    }
    cout << endl;
}

But then at the end you have a lot of delete[]ing to do to free all that memory. So up at the top of your program file:

#include<iostream>
#include<vector>

using namespace std;

And down in main where you are reading in the user's input:

vector<vector<int> > A; //dynamically resizeable array of dynamically resizeable arrays
A.resize(x); // allocate storage for x dimension.
for (i = 0; i < x; i++)
{
    A[i].resize(y); // allocate storage for y dimension for this one x 
    for (j = 0; j < y; j++)
    {
        cin >> A[i][j];
    }
    cout << endl;
}

While I'm editing, there is value in moving the input code to a function so you don't have to repeat it to read in the B matrix.

This vector beastie automatically cleans up after itself when the function ends. Much happy times for all.

Note the space in > > in vector<vector<int> > A; You need this space for older compilers because >> tells the compiler to to shift data right, not terminate a list of template arguments. The poor, confused compiler dumps out a horrific chain of error messages no one wants to wade through or interpret.

Upvotes: 1

Related Questions