Reputation: 11
I'm trying to create an array of structs using dynamic memory allocation. My struct is something along the lines of:
typedef struct {
char data1[200];
char data2[200];
char data3[200];
int data4;
double data5;
double data6;
} randomInfo_t;
I don't know how many of these structs I need to create, which is why I'm using malloc()
to dynamically create the array.
There are multiple lines of data stored within a file, similar to a CSV.
Right now, my attempt at creating the array has lead to a segmentation fault, which I suspect is due to the way I'm using malloc()
:
randomInfo_t *stuffArray;
int indexCounter=0;
while(fgets(buffer, 1024, fp)) {
/* some random code here */
stuffArray[indexCounter] = *(randomInfo_t *)malloc(sizeof(randomInfo_t *));
assert(stuffArray[indexCounter] != NULL);
char *readLine = strtok(buffer, " ");
while(readLine) {
strcpy(randomArray[indexCounter].data1, readLine);
etc...
}
indexCounter++;
}
I've tried debugging it myself, but I have absolutely no clue what I was doing.
Any help is appreciated. Thanks
(PS. I know that using a linked list would be a lot easier, and I would prefer to use one as well, but requirements of the code means no linked lists).
Upvotes: 0
Views: 271
Reputation: 1922
The problem is that stuffArray
is an uninitalized pointer. What you need to do is initalize it and keep track of its current size, like this:
// allocate space for 10 pointers to struct
randomInfo_t **stuffArray = malloc(sizeof(randomInfo_t*) * 10);
int stuffArray_size = 10;
int stuffArray_used = 0;
Then when you are allocating space for another struct pointer you do it like this:
// if there are more structs than what stuffArray can currently fit realloc
if(indexCounter >= stuffArray_size) {
stuffArray_size += 10;
stuffArray = realloc(stuffArray, stuffArray_size * sizeof(randomInfo_t*));
}
stuffArray_used++;
// now we can allocate space for a new struct and point stuffArray[indexCounter] to the newly allocated space
stuffArray[indexCounter] = malloc(sizeof(randomInfo_t));
And now when you want to access struct member you have to use ->
.
So this line:
strcpy(randomArray[indexCounter].data1, readLine);
Now has to be:
strcpy(randomArray[indexCounter]->data1, readLine);
Also when you are done using the array you have to free
it.
Like this:
// this is where the stuffArray_used comes into play, we don't want to try freeing unallocated memory
for(int i = 0; i < stuffArray_used; i++){
free(stuffArray[i]);
}
free(stuffArray);
Upvotes: 1
Reputation: 17513
It is not clear if you are attempting to dynamically allocate an array of randomInfo_t
or an array of randomInfo_t *
with each element pointing to a randomInfo_t
.
Assuming you are dynamically allocating an array of randomInfo_t
you can use realloc
to gradually increase the size of the array:
randomInfo_t *stuffArray=NULL;
int indexCounter=0;
while(fgets(buffer, 1024, fp)) {
/* some random code here */
randomInfo_t *oldStuffArray = stuffArray; /* In case realloc fails */
stuffArray = realloc(stuffArray, sizeof(*stuffArray) * (indexCounter + 1));
if (stuffArray == NULL) {
/*
* realloc failed. Take appropriate action here.
* Note that the memory pointed to by oldStuffArray is still valid.
*/
#if FOO
/* for example: */
fprintf(stderr, "Memory allocation failed\n");
free(oldStuffArray);
exit(1);
#else
/* or you could use oldStuffArray contents and not read any more: */
fprintf(stderr, "Memory allocation failed\n");
stuffArray = oldStuffArray;
break;
#endif
}
/* Do stuff with stuffArray[indexCounter] */
indexCounter++;
}
Upvotes: 1