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.

Dave
  • 10,964
  • 3
  • 32
  • 54
Leavenotrace
  • 3
  • 1
  • 3

4 Answers4

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.

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • Maybe he's thinking of the [`-->`](http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator) "goes to" operator. – Dave Jan 03 '12 at 16:35
  • 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 Jan 07 '12 at 15:06
  • @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++`.) – ruakh Jan 07 '12 at 15:19
0

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

  • 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 – Leavenotrace Jan 03 '12 at 16:30
  • Don't try `*(mat->data)`, just increment the pointer by doing `mat->data++` – user1123450 Jan 03 '12 at 16:40
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]

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;
}
Sangeeth Saravanaraj
  • 16,027
  • 21
  • 69
  • 98