Leavenotrace
Leavenotrace

Reputation: 3

Incrementing a Pointer to an Array within a structure

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.

Upvotes: 1

Views: 3255

Answers (4)

ruakh
ruakh

Reputation: 183280

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.

Upvotes: 4

Sangeeth Saravanaraj
Sangeeth Saravanaraj

Reputation: 16597

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;
}

Upvotes: 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]

Upvotes: 0

user1123450
user1123450

Reputation: 86

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

Upvotes: 0

Related Questions