0

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).

4
  • 3
    stuffArray is a pointer. What is it pointing to? Commented Aug 12, 2021 at 11:44
  • Do you want to allocate memory for an array of randomInfo_t or do you want to allocate memory for an array of randomInfo_t * with each element pointing to a separately allocated randomInfo_t? Your code is all wrong, so it is hard to tell which option you are trying to implement. Commented Aug 12, 2021 at 11:50
  • In both cases, you can use realloc to extend the stuffArray memory dynamically. Commented Aug 12, 2021 at 11:54
  • @IanAbbott I noticed you have experience with C. Could you please look over my answer and tell me if there is anything that stands out as wrong. Due to the nature of the question it is kind of hard to test it. Commented Aug 12, 2021 at 12:07

2 Answers 2

1

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++;
}
Sign up to request clarification or add additional context in comments.

Comments

1

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);

2 Comments

Note that I did write this without testing it because it is kinda tricky to test it with the code you provided but it should give you the general idea.
Since you wanted a review, it looks OK apart from if(indexCounter >= size) { where I think you meant if(indexCounter >= stuffArray_size) {. And you need to store the pointer returned by realloc back to stuffArray.

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.