1

I'm having a bit of trouble doing this and have searched High and low on the internet for help, but to no avail. I'm basically trying to create a random matrix and print it out, I have a function double random() which works and has been tested and I have defined a structure as follows:

    typedef struct matrep {
         unsigned rows, columns;
         double *data;
    } MATRIX;

for which I have allocated memory properly, I use this and my random function to create a random matrix but what happens is the pointer never moves,

MATRIX *rand_matrix( MATRIX *mat ) 
{
    for ( int i=0; i < mat->rows; i++ )
    {
        for ( int j=0; j < mat->columns; j++ )
        {
             *(mat->data) = random() ;
        }
    }
    return mat ;
}

I know it never moves because when I print out the matrix using this function

void print_matrix(MATRIX *mat ) 
{
    int i, j ;
    if ( (mat->data)==0 || (mat->rows)==0 || (mat->columns)==0 )
    {
        printf("Empty matrix\n" );
        return ;       
    }
    printf( "\n\nMatrix of dimensions %d x %d\n\n", mat->rows, mat->columns) ;
    for ( i=0; i < mat->rows; i++ )
    {
        for ( j=0; j < mat->columns; j++ )
        {
            printf("\t%1.2lf", *(mat->data) );
        }
        printf("\n") ;
    }
}

and exchange random in the matrix above with 'j' it ends up printing out a matrix with the correct number of rows and collumns but each value is equal to the biggest value of j.

Basically what I was hoping you could help me with is figuring out how to increment my *(mat->data) pointer. I heard something about when you call the arrow operator it increments automatically but it doesnt seem to be working and when i try *(mat->data)++ I get a nice big error.

Any help would be great thanks a million.

1
  • It doesn't increment automatically. Commented Jan 3, 2012 at 16:28

4 Answers 4

4

You don't actually want to change mat->data; you need it to continue to point at your properly-allocated memory. Instead, you need to change this:

         *(mat->data) = random() ;

to something like this:

         mat->data[i * mat->columns + j] = random() ;

(to refer to the i * mat->columns + jth double in the memory-block pointed to by mat->data), and this:

      printf("\t%1.2lf", *(mat->data) );

to something like this:

      printf("\t%1.2lf", mat->data[i * mat->columns + j]);

(similarly).

I heard something about when you call the arrow operator it increments automatically […]

This is not true, and I can't even think of anything similar that you might have heard, sorry.


Edited to add: Another approach, if you prefer, is to write something like this:

MATRIX *rand_matrix( MATRIX *mat ) 
{
    double *pTmp = mat->data;
    for ( int i=0; i < mat->rows; i++ )
    {
        for ( int j=0; j < mat->columns; j++ )
        {
             *(pTmp++) = random() ;
        }
    }
    return mat ;
}

which increments a pointer pTmp over all the elements. I don't know which approach is more clear. But either way, I don't think it's a good idea to modify mat->data.

Sign up to request clarification or add additional context in comments.

3 Comments

Maybe he's thinking of the --> "goes to" operator.
Thanks very much, I tried the second way pTmp and it worked like a charm, I agree messing with mat->data probably wasn't helping but I'm wondering why adding an extra pointer into the mix makes a difference, surely its just pointing to the same place as before? Sorry if thats a stupid question but I really struggle with pointers
@Leavenotrace: Not a stupid question at all. The extra pointer makes a difference because it's safe to increment it. pTmp starts out just pointing to the same place as mat->data, but the pTmp++ part moves it forward one space. (That's a "post-increment"; the statement *(pTmp++) = random() is equivalent to the statement *pTmp = random() followed by the statement pTmp++.)
0

You should do mat->data++. (mat->data)++ is evaluating the value of mat->data and trying to increment it which is not possible.

2 Comments

even if I change the line *(mat->data) = random() to *(mat->data++) = random() I still end up with a matrix with every number the same only now they are all zeros
Don't try *(mat->data), just increment the pointer by doing mat->data++
0

Here: `printf("\t%1.2lf", *(mat->data) );' you're always pointing at the same memory.

You can use the [] operator to index and dereference a pointer, for example:

(mat->data)[2]

Comments

0

Basically for storing a matrix using array, you need to allocate memory which closely mimics the 2D matrix, i.e. each and every matrix (or array) element should be accessed uniquely using different value for rows into columns.

You can do that in C in many ways. But the following is one of the most common way of doing the same. This lacks the de-allocation i.e. free(). Please try and do that yourself and we are here if you need any help!

NOTE: I can see multiple changes should be done in you code.. and so I'm attempting to provide a generic guidelines and reference as an answer!

#include <stdio.h>
#include <stdlib.h>

int main()
{
        int row, column;
        int **matrix;
        int i, j, val;

        printf("Enter rows: ");
        scanf("%d", &row);
        printf("Enter columns: ");
        scanf("%d", &column);

        matrix = (int **) malloc (sizeof(int *) * row);
        for (i=0 ; i<row ; i++) 
                matrix[i] = (int *) malloc (sizeof(int) * column);

        val=1;
        for (i=0 ; i<row ; i++) {
                for (j=0 ; j<column; j++) {
                        matrix[i][j] = val++;
                }
        }

        for (i=0 ; i<row ; i++) {
                for (j=0 ; j<column; j++) {
                        printf("%3d  ", matrix[i][j]);
                }
                printf("\n");
        }

        return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.