Answered Dynamically Memory Allocation

  • Sunday, August 19, 2012 8:39 PM
     
      Has Code
    #include<iostream>
    #include<conio.h>
    #include<stdio.h>
    
    using namespace std;
    
    int main()
    {
    	int r[20],c[20],i,j,k,n,a,b,sum,m,p;
    	int ***matrix,**product;
    	cout<<"Enter the number of matrices ";
    	cin>>n;
    	for(i=0;i<n;i++)
    	{
    			cout<<"Enter the number of rows of the matrix "<<i+1<<"\n";
    			cin>>r[i];
    			matrix[i]= new int*[r[i]];
    			
    			cout<<"\nEnter the number of columns of matrix "<<i+1<<"\n";
    			cin>>c[i];
    			
    			if(i>=1 && c[i-1]!=r[i])
    			{
    				cout<<"\nThe Product can't be found with such dimensions";
    				exit(0);
    			}
    			
    			for(j=0;j<r[i];j++)
    				matrix[i][j]= new int[c[i]];
    
    			cout<<"\nEnter the elements of the matrix "<<i+1<<"\n";
    			for(j=0;j<r[i];j++)
    				for(k=0;k<c[i];k++)
    					cin>>matrix[i][j][k];
    	}
    	
    	a=r[0];
    	b=c[n];
    	product= new int*[a];
    	for(i=0;i<a;i++)
    		product[i]=new int[b];
    
    	m=0;
    		for(i=0;i<r[0];i++)
    			for(j=0;j<c[n];j++)
    			{	
    				product[i][j]=0;
    				for(k=0;k<r[m];k++)
    					product[i][j]=product[i][j] + matrix[m][i][k]*matrix[m+1][k][j];
    			}
    
    		cout<<"The Product of the Matrices is: \n";
    
    		for(i=0;i<r[0];i++)
    		{	
    			cout<<"\n";
    			for(j=0;j<c[n];j++)
    				cout<<product[i][j]<<"\t";
    		}
    
    		for(i=0;i<c[i];i++)
    			delete []matrix[i];
    		delete []matrix;
    
    	getch();
    	return 0;
    }

    Program to calculate product of matrices. Right now it is just for 2 matrices but Showing run-time error in the underlined lines in starting saying expression cannot be evaluated.Yes, the code is quite complex, not very easy to understand.I have used three pointers so that i can use matrix[i] as a variable and input as many matrices as i want, i think you will understand.

    I think i have done something wrong. Please guide me.




    • Edited by wincod Sunday, August 19, 2012 8:41 PM
    • Edited by wincod Sunday, August 19, 2012 8:42 PM
    • Edited by wincod Sunday, August 19, 2012 8:43 PM
    •  

All Replies

  • Sunday, August 19, 2012 9:43 PM
     
     Answered

    amitmac wrote:

    a=r[0];
    b=c[n];

    c[n] was never assigned a value. You've only initialized c[i] for i from  0 through n-1.


    Igor Tandetnik

    • Marked As Answer by wincod Tuesday, August 28, 2012 4:22 PM
    •  
  • Sunday, August 19, 2012 9:46 PM
     
     Answered
    >int ***matrix,**product;

    >matrix[i]= new int*[r[i]];

    For starters, this is a bug. The pointer "matrix" is
    uninitialized, so you can't use it in the expression
    matrix[i] without dire consequences.

    - Wayne

    • Marked As Answer by wincod Tuesday, August 28, 2012 4:22 PM
    •  
  • Sunday, August 19, 2012 10:20 PM
     
     Answered

    Since r[] and c[] can hold data for up to 20 matrices, you can either change the definition of matrix to
         int **matrix[0];
    to be consistent with the definitions of r and c or you can dynamically allocate it prior to the "i" for loop with
         matrix = new int**[n];
    As it stands now, the value of matrix is indeterminate and the expressions matrix[i] and matrix[i][j] both invoke undefined behavior.

    You obviously expect n to be 20 or less.  It would be good to inlcude that information in the prompt and to test the value before using it.

    If n < 20, c[n] is indeterminate.  If n >= 20, c[n] does not exist.  In either case, evaluating the expression c[n] inovkes undefined behavior.  You want to set b to c[n-1].

    Consider adopting a coding style with a little more horizontal white space:
         for (i=0; i < n; i++)
    is a lot easier to read than
        
    for(i=0;i<n;i++)
    The compiler doesn't care but it will make it much easier on anyone (including you) trying to read the code.

    You are obviously coding in C++ but two of your headers are the C version.  You should get in the habit of using the C++ versions.  (It may not matter for this program but it probably will make a difference at some point.)

    Every new should have a corresponding delete and vice versa.  You execute numerous "new" statements for matrix[i][j] but no "delete" statements.  You execute a "delete" statement for matrix but there is no corresponding "new" statement.

    • Marked As Answer by wincod Tuesday, August 28, 2012 4:22 PM
    •  
  • Monday, August 20, 2012 6:24 PM
     
      Has Code
    #include<iostream>
    #include<conio.h>
    
    using namespace std;
    
    int main()
    {
    	int **r, **c, i, j, k, n, a, b, p, q, m;
    	int ***matrix, ***product;
    	cout << "Enter the number of matrices ";
    	cin >> n;
            //memory allocation
    	matrix = new int**[n];
    	r = new int*[n];
    	c = new int*[n];
    	
    	for(i=0 ; i < n ; i++)
    	{
    			//input rows number
    			cout << "Enter the number of rows of the matrix "<< i+1 <<"\n";
    			cin >> a;
    
    			//allocating memory
    			r[i] = new int[a];
    
    			matrix[i] = new int*[r[i][a]];
    			
    			//input columns
    			cout << "\nEnter the number of columns of matrix "<< i+1 <<"\n";
    			cin >> b;
    			c[i] = new int[b];
    
    			//checking whether the matrices product can be calculated
    			if( i >= 1 && c[i-1][b] != r[i][a])
    			{
    				cout << "\nThe Product can't be found with such dimensions";
    				_getch();
    				exit(0);
    			}
    			//allocating memory to matrix
    			for(j=0 ; j < r[i][a] ; j++)
    				matrix[i][j]= new int[c[i][b]];
    
    			//input elements of matrices
    			cout<<"\nEnter the elements of the matrix "<<i+1<<"\n";
    			for(j=0 ; j < r[i][a] ; j++)
    				for(k=0 ; k < c[i][b] ; k++)
    					cin >> matrix[i][j][k];
    	}
    	
    	p = r[0][a];
    	q = c[n-1][b];
    
    
    	product= new int**[p];
    	//dynamically allocating memory
    	for(i = 0 ; i < a ; i++)
    		product[i] = new int*[b];
    
    	//calculating the product of the matrices
    	for(m = 0 ; m < n ; m++)
    	{
    		p = r[m][a];
    		q = c[m][b];
    		for(i = 0 ; i < p ; i++)
    			for(j = 0 ; j < q ; j++)
    			{	
    				product[i][j] = 0;
    
    				for(k = 0 ; k < r[i][m] ; k++)
    					product[i][j] = product[i][j] + matrix[m][i][k] * matrix[m+1][k][j];
    			}
    	}
    		cout<<"The Product of the Matrices is: \n";
    		//output the elements
    		for( i = 0 ; i < r[i][0] ; i++)
    		{	
    			cout<<"\n";
    			for(j = 0 ; j < c[j][n-1] ; j++)
    				cout<< product[i][j] <<"\t";
    		}
    		
    		//deallocating dynamic memory
    		for(i = 0 ; i < n ; i++)
    		{	
    			for(j = 0 ; j < r[i][a] ; j++)
    			{
    				delete []matrix[i][j];
    			}
    			delete []matrix[i];
    		}
    
    	_getch();
    	return 0;
    }

    Here are some changes i made. Now i initialized the matrix which i did not before and also now i tried to allocate memory
    to rows and columns dynamically but i am not able to do it correctly.
    It is again runtime error(debug error) saying invalid allocation size: 4294967295 bytes. 
    I am missing some concepts. Please help me learning these concepts.

    I know you may get irritate of me again getting such error but please cooperate.

    • Edited by wincod Monday, August 20, 2012 6:28 PM
    •  
  • Monday, August 20, 2012 6:36 PM
     
     Answered

    On 8/20/2012 2:24 PM, amitmac wrote:

                //input rows number
                cout << "Enter the number of rows of the matrix "<< i+1 <<"\n";
                cin >> a;

                //allocating memory
                r[i] = new int[a];

                matrix[i] = new int*[r[i][a]];

    r[i] was just allocated a line above; no values are assigned to its elements. Besides, r[i] points to an array of 'a' integers, indexed 0 through a-1. r[i][a] was never even allocated, let alone initialized.

    It's not clear why you decided to make 'r' an int**, a 2d array. You just need one number per matrix there.


    Igor Tandetnik

    • Marked As Answer by wincod Tuesday, August 28, 2012 4:22 PM
    •  
  • Monday, August 20, 2012 6:57 PM
     
     
    yeah....thanks a lot.....that was unnecessary. I got it now. I thought in some other way. Its working now. Thanks a lot.....but there can be further problems created in the same so i am not closing it here.
    For now i got it right.
  • Monday, August 20, 2012 10:04 PM
     
     Answered

    I don't know why you decided to change r and c from arrays to dynamically allocated areas.  If you thought you were saving memory, the answer is probably not.  Even when asking for small blocks, most allcoation schemes allocate in multiples of 1k or 4K.  Dynamic allocation makes sense when you may need to resize or when you have no reasonable upper limit.

    Since the original r and c were arrays of int, the logical conversion would be to int *, not int** and the allocation would be for n int, not n int*.

    Allocated memory is not initialized.  The expression r[i][a] has two problems.  r[i] contains the address of a block of memory capable of holding (a) int.  Treating this as an array allows you to use subscripts of the form r[i][j] where j can run from 0 to (a-1).  So r[i][a] does not exist and attempting to evaluate it invokes undefined behavor.  Even changing the second subscript to one within range invokes undefined behavior since the value of that int is indeterminate.  c[i-1][b] has the same problem.

    Once you fix r and c, When you ask for the number of rows, store the result directly in r[i].  Store the number of columns directly in c[i].  Then it makes sense to ask if c[i-1] == r[i].

    Don't you need stdlib.h or the C++ equivalent for exit()?  In any case, in the error logic where you call exit(), I suggest using EXIT_FAILURE as the return code since 0 from main usually means success.

    • Marked As Answer by wincod Tuesday, August 28, 2012 4:22 PM
    •