1

I am having trouble with following struct for using it as Matrix

  struct{
         int col;
         int row;
         int (*p)[col];//In this line compiler is giving error, saying col undeclared here.
  }Matrix;

I searched on internet and I found a solution which says to write

  int (*p)[col] 

as

 int (*p)[]

Compiler passes it, no issues.

But when I want to increment p using Matrix variable say m

++(m.p);

compiler gives another errors (two) in the same line of code, which says

increment of pointer to unknown structure.
arithmetic on pointer to an incomplete type.

Please tell me why the compiler is giving the above mentioned errors?

What I finally want is to have a pointer in the structure which points to 2-d dynamic array of integers. So,How to do it???

3 Answers 3

2

If you truly want a pointer to an arbitrary 2d array that changes, you will have to use a void pointer. (I don't recommend it, it's unsafe, design should probably be changed.)

struct
{
     int col;
     int row;
     void* p;
}

Before you access the memory, use a local variable-length array pointer. Take the void pointer in the struct, and assign to it the local vla pointer, using the information from the struct:

struct Matrix x = ...;

int (*n)[x.col] = x.p;

And then use it:

n[0][0] = ... 

If you want to increment the void pointer in the struct, simply increment the local pointer, and assign it back to the void pointer:

n++;
x.p = n;

No casting is necessary, just a declaration of a local pointer. If that is a nuisance, operations on void pointer in the struct can be abstracted using inline functions. This should also be done for the sake of safety.

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

4 Comments

then what would be the point of using struct as an abstraction??
@Rouftantical The struct holds the raw pointer to memory and its dimensions. Defining a local pointer is hardly a nuisance, and if it is for some reason, use get-set functions.
still it would be a headache of casting
@Rouftantical Actually, since it is a void pointer, no casting is necessary. See the example.
1

The field declaration int (*p)[col]; is not valid because the compiler don't know the value of col. What you need is a pointer to a pointer, int **p, where p[i] designates the i:th row in the two-dimensional array.

Here is a complete example with a convenient memory allocation macro:

#include <stdlib.h>

#define NEW_ARRAY(ptr, n) (ptr) = calloc((n) * sizeof (ptr)[0], sizeof (ptr)[0])

struct Matrix {
    int rows;
    int cols;
    int **items;
};

void InitializeMatrix(int rows, int cols, struct Matrix *A)
{
    int i;

    A->rows = rows;
    A->cols = cols;
    NEW_ARRAY(A->items, rows);
    for (i = 0; i < rows; i++) {
        NEW_ARRAY(A->items[i], cols);
    }
}


int main(void)
{
    struct Matrix A;

    InitializeMatrix(10, 20, &A);
    return 0;
}

3 Comments

why you did sizeof(ptr)[0], can I write sizeof (ptr) alone?
@Rouftantical It's the array element size. In this context the element is either a matrix row or a matrix element. If you used sizeof (ptr) you would get the size of the pointer, which is not what you want.
@Rouftantical I also changed malloc to calloc to make all elements zero.
0

When an array is declared then the memory needs to be allocated separately.

struct Matrix{
         int col;
         int row;
         int  *Matrix[100];
      };

More flexibile:

struct Matrix{
         int col;
         int row;
         int  **Matrix;
      }


struct Matrix A;

A.col =10;
A.row = 10;

/* Allocate memory here for the Matrix */

You can declare and allocate memory for a 2D arrays using different methods.

/* Access the Matrix */ A.Matrix[i][j] = value;

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.