Reputation: 8602
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
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
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
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