andrei
andrei

Reputation: 8602

Matrix of pointers with mixed data types in C

I am trying to define a matrix like so I have a structure

typedef struct _struct {
  int name;
  int data;
} myDataType;

Afterwards i am defining a matrix

int **myMatrix = calloc(size,sizeof(int*));
for()
   // allocate rows except last index
myMatrix[last_index_in_matrix] = calloc(1,sizeof(myDataType));

The problem is that I cannot access myMatrix[last_index].data it says, also tried with -> (i really don't know when to use what)

request for member ‘data’ in something not a structure or union

What am i doing wrong ? Should i post actual code ? If this method is not possible can i get a different suggestion ?

UPDATE: I'll say it again, the matrix is all int, i just want the last row to point to that structure, some of the comments have not taken this into consideration. That is way i declared it the way i did in my example.

Upvotes: 0

Views: 775

Answers (3)

John Bode
John Bode

Reputation: 123596

Let's start simple:

You want to create a matrix of myDataType. If you know the number of rows and columns at compile time, you can simply declare it as

myDataType matrix[ROWS][COLS];

If you need to allocate it dynamically, you would do something like this:

myDataType **matrix;

matrix = calloc(rows, sizeof *matrix);
if (matrix)
{
  size_t r;
  for (r = 0; r < rows; r++)
  {
    matrix[r] = calloc(cols, sizeof *matrix[r]);
  }
}

Either way, to access the struct members at the i'th and j'th elements, you'd write:

matrix[i][j].name = ...;
matrix[i][j].data = ...;

Edit

Ah, now I get it.

Don't do that.

There's no guarantee that pointers to struct types have the same size and representation as pointers to int. They do on most common architectures, but it's not something you can rely on. If they don't, then you're going to have runtime problems.

From a design point of view this just makes me itchy; if you need to associate that struct with a matrix, create a new aggregate type to explicitly do so:

struct composite
{
  int **matrix;
  struct myData data;
};

This will make life easier when you need to free up the matrix as well.

FWIW, to do what you wanted, you'd need to engage in some casting gymnastics such as

(struct myData *) myMatrix[last_index] = malloc(sizeof (struct myData));

and

((struct myData *) myMatrix[last_index])->data = ...;

but as I said above, if the pointer types are not compatible, the conversion could lead to runtime errors. Don't do it. Bad juju.

Upvotes: 2

Sangeeth Saravanaraj
Sangeeth Saravanaraj

Reputation: 16637

The following is what you should do to allocate a 2d matrix dynamically using malloc()

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

#define ROW 10    
#define COL 10

int main(void) 
{
    char **arr = NULL;
    int i;

    if ((arr = malloc(sizeof(char *) * ROW)) == NULL) {
        printf("unable to allocate memory \n");
        return -1;
    }

    for (i=0; i<ROW ; i++) {
        if ((arr[i] = malloc(sizeof(char) * COL)) == NULL) {
            printf("unable to allocate memory \n");
            return -1;
        }
    }

    /* here you can use arr[][] */

    for (i=0; i<ROW ; i++) 
        free(arr[i]);
    free(arr);

    return 0;
}

OTOH, to access the following struct member variables you have the following ways

typedef struct _struct {
  int name;
  int data;
} myDataType;

Option #1

/* creating auto variable of type myDataType which gets allocated in stack */
myDataType mdt;

/* to access the member variables, you need to do the following */
mdt.data = 10

Option #2

/* creating a pointer variable of type myDataType 
   and allocating memory from heap using malloc() */
myDataType *pmdt = NULL;

if ((pmdt = malloc(sizeof(myDataType) * numberofelements)) == NULL) {
    printf("unable to allocate memory \n")
    return -1;
}

/* to access the member variables using the pointer, you need to do the following */
pmdt->data = 100;

/* finally you should free the memory allocated using malloc() using free() */
free(pmdt);

Hope it helps!


Based on the request from the OP author, combining the above two programs into one.

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

#define ROW 10    
#define COL 10

typedef struct _struct {
  int data;
} myDataType;

int main(void) 
{
    myDataType **arr = NULL;
    int i, j;
    int val = 0;

    if ((arr = malloc(sizeof(myDataType *) * ROW)) == NULL) {
        printf("unable to allocate memory \n");
        return -1;
    }

    for (i=0; i<ROW ; i++) {
        if ((arr[i] = malloc(sizeof(myDataType) * COL)) == NULL) {
            printf("unable to allocate memory \n");
            return -1;
        }
    }

    /* Now, I'm setting some value to each 
       and every element in the 2d matrix */
    for (i=0; i<ROW ; i++)
        for (j=0; j<COL ; j++)
        arr[i][j].data = val++;

    /* Now, I'm printing those values */
    for (i=0; i<ROW ; i++)
        for (j=0; j<COL ; j++) 
        printf("arr[%d][%d].data = %d \n", i, j, arr[i][j].data);

    for (i=0; i<ROW ; i++) 
        free(arr[i]);
    free(arr);

    return 0;
}

Upvotes: 0

StasM
StasM

Reputation: 11082

You should convert the pointer to the appropriate type:

int val = ((MyDataType *)myMatrix[last_index_in_matrix])->data

otherwise you try to find a field named data in int * which of course can not be done. Alternatively, declare myMatrix as MyDataType **.

Upvotes: 1

Related Questions