Reputation: 159
I am trying to create a dynamic array of dynamic structs but I can't get it working properly. It prints all the info but it gives return error. If I comment the line containing:
printf(" m[%i][%i] ID: %i VALUE: %f\n", i, j, m[i]->id, m[i]->values[j]);
It compiles OK and returns 0. What am I doing wrong? I am just beginning learing C and in the process of dealing with pointers.
#include <stdio.h>
#include <stdlib.h>
typedef struct listDef{
int id;
float *values;
} ListSt;
int main()
{
int max_fil, fil, col;
max_fil = 4; /* Max 'ListSt' elements*/
fil=2; /* Rows */
col=4; /* Columns */
ListSt **m = NULL;
int count = 0;
int sizes[] = {4,6,8,10}; /* The sizes of each 4 elements to be created */
m = (ListSt **)malloc(sizeof(int*)*max_fil); /* Assign a memory address for accesing 'm' (ListSt) */
for(int i=0;i<fil;i++){
m[i]->values = (float *)malloc(sizeof(float)*sizes[i]);
m[i]->id = i;
printf("-----------\n");
printf("Element n.%i :\n\n", i);
for(int j=0;j<sizes[i];j++){
m[i]->values[j] = 0.1234*(i+1);
/* If I comment the next line, it compiles OK. */
printf(" m[%i][%i] ID: %i VALUE: %f\n", i, j, m[i]->id, m[i]->values[j]);
int testint;
float testfloat;
testint = m[i]->id;
testfloat = m[i]->values[j];
}
}
free(m);
return 0;
}
Upvotes: 0
Views: 150
Reputation: 159
The final working code, for if it can help someone:
#include <stdio.h>
#include <stdlib.h>
int max_fil, count;
typedef struct listDef{
float *values;
int id;
int nElements;
} ListSt;
ListSt ListSt_init(ListSt *m, int i, int s){
m[i].values = (float *)malloc(sizeof(float)*s);
printf("-----------\n");
printf("CREATE Element n.%i :\n\n", i);
for(int j=0;j<s;j++){
m[i].id = i;
m[i].nElements = s;
m[i].values[j] = 0.0000 + count*(0.1);
printf("m[%i][%i] ID: %i TotalElements: %i Value[%i]: %f\n", i, j, m[i].id, m[i].nElements, j, m[i].values[j]);
count++;
}
return m[i];
}
int main()
{
max_fil = 100; /* Max 'ListSt' elements addresses to be created */
count = 0; /* Just a global counter for each 'values' */
int sizes[] = {4,8,4}; /* The sizes of each 4 elements to be created */
ListSt *m = NULL;
m = (ListSt *)malloc(sizeof (ListSt) * max_fil); /* Assign a memory address for accesing 'm' (ListSt) */
/* Lets create three lists */
m[0] = ListSt_init(m, 0, sizes[0]);
m[1] = ListSt_init(m, 1, sizes[1]);
m[2] = ListSt_init(m, 2, sizes[2]);
printf("\n-----------\n");
printf("PRINT RESULT :\n");
printf("-----------\n\n");
/* Now we show the elements.... */
for(int i=0;i<3;i++){
printf("RESULT Element n.%i :\n\n", i);
for(int j=0;j<sizes[i];j++){
printf("m[%i][%i] ID: %i TotalElements: %i Value[%i]: %f\n", i, j, m[i].id, m[i].nElements, j, m[i].values[j]);
}
}
free(m);
return 0;
}
Upvotes: 0
Reputation: 159
I have changed the line:
return *m;
with:
return m[i];
And it works as expected!
Upvotes: 0
Reputation: 159
OK. I think I have it. If someone, please, could maybe check it, it would be great to have some comments about the possible errors or future problems, or just some improvements.
Here's the (modified) working code:
#include <stdio.h>
#include <stdlib.h>
typedef struct listDef{
int id;
float *values;
} ListSt;
int main()
{
int max_fil, fil, col;
max_fil = 4; /* Max 'ListSt' elements*/
fil=4; /* Elements */
ListSt *m = NULL;
int count = 0;
int sizes[] = {4,6,8,10,12,13}; /* The sizes of each 4 elements to be created */
m = (ListSt *)malloc(sizeof (ListSt) * fil); /* Assign a memory address for accesing 'm' (ListSt) */
for(int i=0;i<fil;i++){
m[i].values = (float *)malloc(sizeof(float)*sizes[i]);
printf("-----------\n");
printf("Element n.%i :\n\n", i);
for(int j=0;j<sizes[i];j++){
m[i].id = i;
m[i].values[j] = 0.0001*(i+1)*(j+1);
printf(" m[%i][%i] id: [%i] val: %f\n", i, j, m[i].id, m[i].values[j]);
}
}
free(m);
return 0;
}
And it prints:
-----------
Element n.0 :
m[0][0] id: [0] val: 0.000100
m[0][1] id: [0] val: 0.000200
m[0][2] id: [0] val: 0.000300
m[0][3] id: [0] val: 0.000400
-----------
Element n.1 :
m[1][0] id: [1] val: 0.000200
m[1][1] id: [1] val: 0.000400
m[1][2] id: [1] val: 0.000600
m[1][3] id: [1] val: 0.000800
m[1][4] id: [1] val: 0.001000
m[1][5] id: [1] val: 0.001200
-----------
Element n.2 :
m[2][0] id: [2] val: 0.000300
m[2][1] id: [2] val: 0.000600
m[2][2] id: [2] val: 0.000900
m[2][3] id: [2] val: 0.001200
m[2][4] id: [2] val: 0.001500
m[2][5] id: [2] val: 0.001800
m[2][6] id: [2] val: 0.002100
m[2][7] id: [2] val: 0.002400
-----------
Element n.3 :
m[3][0] id: [3] val: 0.000400
m[3][1] id: [3] val: 0.000800
m[3][2] id: [3] val: 0.001200
m[3][3] id: [3] val: 0.001600
m[3][4] id: [3] val: 0.002000
m[3][5] id: [3] val: 0.002400
m[3][6] id: [3] val: 0.002800
m[3][7] id: [3] val: 0.003200
m[3][8] id: [3] val: 0.003600
m[3][9] id: [3] val: 0.004000
Process returned 0 (0x0) execution time : 0.106 s
Press any key to continue.
Upvotes: 0
Reputation: 4430
m
should be of type "pointer to ListSt
", not "pointer to pointer to ListSt
".
You are allocating memory for an array of pointers:
m = (ListSt **)malloc(sizeof(int*)*max_fil);
... but the elements the array remain uninitialized.
And by the way, that should be
sizeof (ListSt *) * (sizeof (sizes) / sizeof (* sizes))
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
size of an element number of elements in array "sizes"
You then go on and use the value of m[0]
, but you have never assigned a value to m[0]
. This is called undefined behavior; at this point the program is free to do whatever it pleases, for example crashing with segmentation fault.
More specifically, you say m[i]->values =
, but m[i]
is an uninitialized variable, so m[i]->
dereferences an uninitialized pointer.
Upvotes: 1