Thread: Pointer to a 2d array

  1. #16
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Quote Originally Posted by nadroj
    if you have a problem implementing it or you're getting an error, post all of your code and the exact and complete error/warning message(s).
    <filler>

  2. #17
    Registered User
    Join Date
    Dec 2009
    Posts
    24
    Header File:
    Code:
    /* File: matrix.h */
    #ifndef MATRIXh
    #define MATRIXh
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #define FORMAT "%8.3lf"
    
    
    
    typedef struct {
      int  rowdim, coldim;
      double** element;
    } matrix;
    
    /* function prototypes */
    matrix create_empty(int rdim, int cdim);
    matrix create_initval(int rdim, int cdim, double* values);
    void destroy(matrix);
    void matrix_print(matrix a);
    double retrieve(int row, int col, matrix m);  /* retrieve an element from m */
    /* void assign(int row, int col, matrix*, T val); /* assign a value to an element of m */
    void equate(matrix* m1, matrix* m2);  /* m1 = m2 */
    matrix add(matrix, matrix);
    matrix subtract(matrix, matrix);
    matrix negate(matrix);
    matrix multiply(matrix, matrix);
    /* matrix scalar_multiply(T scalar, matrix); */
    /* remaining function prototypes not shown */
    
    #endif
    Function Decelerations:
    Code:
    #include "matrix.h"
    
    matrix create_empty(int rdim, int cdim)
    {
    	matrix new_matrix;
    	new_matrix.element = malloc(sizeof(matrix));
    	new_matrix.rowdim = rdim;
    	new_matrix.coldim = cdim;
    	new_matrix.element = malloc((rdim*cdim) * sizeof(double));
    	return new_matrix;
    }
    
    matrix create_initval(int rdim, int cdim, double* values)
    {
    	int i, j, k;
    	matrix new_matrix;
    	new_matrix.rowdim = rdim;
    	new_matrix.coldim = cdim;
    	new_matrix.element = malloc(sizeof(double*) * rdim);
    	for (k=0; k<rdim; k++)
    		new_matrix.element[k] = malloc(sizeof(double) * cdim);
    	for (i=0; i<cdim; i++)
    	{
    		for(j=0; j<rdim; j++)
    			new_matrix.element[i][j] = values[i][j]; // does not work
    	{
    return new_matrix;
    }
    
    void destroy(matrix a)
    {
    	free(a.element);
    }
    
    void matrix_print(matrix a)
    {
    	int i, j;	
    	printf("\n");
    	for (i=0; i<a.coldim; i++)
    	{
    		for(j=0; i<a.rowdim; j++)
    		{
    			printf(" %f ", a.element[i][j]);
    		}
    	}
    }
    }
    }
    Test File:
    Code:
    #include "matrix.h"
    
    int main()
    {
    	double one[2][3] = {
    						 {1,2,3},
                                                     {4,5,6}
    					   };
    							
    
    	matrix m_one;
    	m_one = create_initval(2, 3, one);
    	matrix_print(m_one);
    return 0;
    }
    Errors:
    matrix.c: In function ‘create_initval’:
    matrix.c:25: error: subscripted value is neither array nor pointer
    test.c: In function ‘main’:
    test.c:12: warning: passing argument 3 of ‘create_initval’ from incompatible pointer type

  3. #18
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Quote Originally Posted by nadroj
    If you declare the array of values as
    Code:

    double one[2][3]

    then the argument to the function can be the same, like
    Code:

    matrix create_initval(int rdim, int cdim, double values[2][3])
    Quote Originally Posted by M-S-H
    i made all those corrections, but i still get the same compile error:
    Quote Originally Posted by M-S-H
    Code:
    matrix create_initval(int rdim, int cdim, double* values)
    This is why I say to post all of your code. Because I told you how to fix it, then you said you fixed it and say the error is still there. Its quite frustrating when I make suggestions and you ignore them.

    EDIT: Also, you still need to "free" the values properly, or there will be memory leaks (I described this earlier). Also, you should verify that "malloc" doesn't return "null) (as described in the link I gave earlier).
    Last edited by nadroj; 02-15-2010 at 10:49 PM.

  4. #19
    Registered User
    Join Date
    Dec 2009
    Posts
    24
    I changed all my code to

    Code:
    /* File: matrix.h */
    #ifndef MATRIXh
    #define MATRIXh
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #define FORMAT "%8.3lf"
    
    
    
    typedef struct {
      int  rowdim, coldim;
      double** element;
    } matrix;
    
    /* function prototypes */
    matrix create_empty(int rdim, int cdim);
    matrix create_initval(int rdim, int cdim, double values[rdim][cdim]);
    void destroy(matrix);
    void matrix_print(matrix a);
    double retrieve(int row, int col, matrix m);  /* retrieve an element from m */
    /* void assign(int row, int col, matrix*, T val); /* assign a value to an element of m */
    void equate(matrix* m1, matrix* m2);  /* m1 = m2 */
    matrix add(matrix, matrix);
    matrix subtract(matrix, matrix);
    matrix negate(matrix);
    matrix multiply(matrix, matrix);
    /* matrix scalar_multiply(T scalar, matrix); */
    /* remaining function prototypes not shown */
    
    #endif
    Code:
    #include "matrix.h"
    
    matrix create_empty(int rdim, int cdim)
    {
    	matrix new_matrix;
    	new_matrix.element = malloc(sizeof(matrix));
    	new_matrix.rowdim = rdim;
    	new_matrix.coldim = cdim;
    	new_matrix.element = malloc((rdim*cdim) * sizeof(double));
    		if(new_matrix.element == NULL)
    		{
    		fprintf(stderr, "out of memory\n");
    		exit(0);
    		}
    	return new_matrix;
    }
    
    matrix create_initval(int rdim, int cdim, double values[rdim][cdim])
    {
    	int i, j, k;
    	matrix new_matrix;
    	new_matrix.rowdim = rdim;
    	new_matrix.coldim = cdim;
    	new_matrix.element = malloc(sizeof(double*) * rdim);
    	if(new_matrix.element == NULL)
    		{
    		fprintf(stderr, "out of memory\n");
    		exit(0);
    		}
    
    	for (k=0; k<rdim; k++)
    		new_matrix.element[k] = malloc(sizeof(double) * cdim);
    		if(new_matrix.element[k] == NULL)
    		{
    		fprintf(stderr, "out of memory\n");
    		exit(0);
    		}
    
    	for (i=0; i<cdim; i++)
    	{
    		for(j=0; j<rdim; j++)
    			new_matrix.element[i][j] = values[i][j]; // does not work
    	{
    return new_matrix;
    }
    
    void destroy(matrix a)
    {
    	free(a.element);
    }
    
    void matrix_print(matrix a)
    {
    	int i, j;	
    	printf("\n");
    	for (i=0; i<a.coldim; i++)
    	{
    		for(j=0; i<a.rowdim; j++)
    		{
    			printf(" %f ", a.element[i][j]);
    		}
    	}
    }
    }
    }
    Code:
    #include "matrix.h"
    
    int main()
    {
    	double one[2][3] = {
    									     {1,2,3},
                                    {4,5,6}
    										};
    							
    
    	matrix m_one;
    	m_one = create_initval(2, 3, one);
    	matrix_print(m_one);
    return 0;
    }
    now the array seems to be passed in fine, but theres a problem with the print statement. when i compile both .c files, i get this:
    /tmp/cce6gQuE.o: In function `main':
    test.c.text+0x7d): undefined reference to `matrix_print'
    collect2: ld returned 1 exit status

  5. #20
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    In "create_initval"
    Code:
    	for (i=0; i<cdim; i++)
    	{
    		for(j=0; j<rdim; j++)
    			new_matrix.element[i][j] = values[i][j]; // does not work
    	{
    The brace there should probably be a close one, not an open one. After fixing that, if you get other errors, make sure all of your brackets line up.

  6. #21
    Registered User
    Join Date
    Dec 2009
    Posts
    24
    i fixed the bracket, and it compiled fine, but when i ran it,
    a null must have been returned because it displayed "out of memory"
    now how do i fix that?

  7. #22
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    I told you before that you should make the array argument to "create_initval" to "double values[2][3]", if you know that the values are going to be 2, 3. In this case, you don't need to pass the dimensions, since they are fixed at 2, 3.

    It is unlikely that they will probably be fixed dimensions. In this case, you need to make the array "one" in "main" a dynamic 2-d array, also, just like the "element" 2-d "array". So
    Code:
    double one[2][3];
    would become
    Code:
    double ** one;
    then you allocate it in the same way as the "element" array. First the rows, then the columns. Doing it this way requires you to keep the dimensions as arguments to "create_initval", but the trade off is that the array can be arbitrary non-constant size. So the last argument in
    Code:
    matrix create_initval(int rdim, int cdim, double values[rdim][cdim])
    would become "double ** values", and you should be able to use it the same way you are now. "one" would also be passed the same way it is now, once you change the rest to use **.

    I'm leaving now, so I'll let you do some independent thinking/learning and debugging.
    Last edited by nadroj; 02-15-2010 at 11:41 PM.

  8. #23
    Registered User
    Join Date
    Dec 2009
    Posts
    24
    Alright, thanks so much for all your help. I really appreciate it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. prinitng 2D array form pointer ????
    By fcommisso in forum C Programming
    Replies: 6
    Last Post: 11-02-2009, 09:58 PM
  2. from 2D pointer to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 2
    Last Post: 07-20-2009, 08:58 AM
  3. from 2D array to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 17
    Last Post: 03-24-2009, 10:33 AM
  4. 2D array pointer
    By taurus in forum C Programming
    Replies: 15
    Last Post: 10-30-2008, 12:30 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM