How can I create a dynamically sized array of structs?

后端 未结 10 1132
春和景丽
春和景丽 2020-11-27 11:46

I know how to create an array of structs but with a predefined size. However is there a way to create a dynamic array of structs such that the array could get bigger?

<
相关标签:
10条回答
  • 2020-11-27 12:18

    This looks like an academic exercise which unfortunately makes it harder since you can't use C++. Basically you have to manage some of the overhead for the allocation and keep track how much memory has been allocated if you need to resize it later. This is where the C++ standard library shines.

    For your example, the following code allocates the memory and later resizes it:

    // initial size
    int count = 100;
    words *testWords = (words*) malloc(count * sizeof(words));
    // resize the array
    count = 76;
    testWords = (words*) realloc(testWords, count* sizeof(words));
    

    Keep in mind, in your example you are just allocating a pointer to a char and you still need to allocate the string itself and more importantly to free it at the end. So this code allocates 100 pointers to char and then resizes it to 76, but does not allocate the strings themselves.

    I have a suspicion that you actually want to allocate the number of characters in a string which is very similar to the above, but change word to char.

    EDIT: Also keep in mind it makes a lot of sense to create functions to perform common tasks and enforce consistency so you don't copy code everywhere. For example, you might have a) allocate the struct, b) assign values to the struct, and c) free the struct. So you might have:

    // Allocate a words struct
    words* CreateWords(int size);
    // Assign a value
    void AssignWord(word* dest, char* str);
    // Clear a words structs (and possibly internal storage)
    void FreeWords(words* w);
    

    EDIT: As far as resizing the structs, it is identical to resizing the char array. However the difference is if you make the struct array bigger, you should probably initialize the new array items to NULL. Likewise, if you make the struct array smaller, you need to cleanup before removing the items -- that is free items that have been allocated (and only the allocated items) before you resize the struct array. This is the primary reason I suggested creating helper functions to help manage this.

    // Resize words (must know original and new size if shrinking
    // if you need to free internal storage first)
    void ResizeWords(words* w, size_t oldsize, size_t newsize);
    
    0 讨论(0)
  • 2020-11-27 12:23

    Every coder need to simplify their code to make it easily understood....even for beginners.

    So array of structures using dynamically is easy, if you understand the concepts.

    // Dynamically sized array of structures
    
    #include <stdio.h>
    #include <stdlib.h>
    
    struct book 
    {
        char name[20];
        int p;
    };              //Declaring book structure
    
    int main () 
    {
        int n, i;      
    
        struct book *b;     // Initializing pointer to a structure
        scanf ("%d\n", &n);
    
        b = (struct book *) calloc (n, sizeof (struct book));   //Creating memory for array of structures dynamically
    
        for (i = 0; i < n; i++)
        {
            scanf ("%s %d\n", (b + i)->name, &(b + i)->p);  //Getting values for array of structures (no error check)
        }          
    
        for (i = 0; i < n; i++)
        {
            printf ("%s %d\t", (b + i)->name, (b + i)->p);  //Printing values in array of structures
        }
    
        scanf ("%d\n", &n);     //Get array size to re-allocate    
        b = (struct book *) realloc (b, n * sizeof (struct book));  //change the size of an array using realloc function
        printf ("\n");
    
        for (i = 0; i < n; i++)
        {
            printf ("%s %d\t", (b + i)->name, (b + i)->p);  //Printing values in array of structures
        }
    
        return 0;
    }   
    
    0 讨论(0)
  • 2020-11-27 12:24

    Here is how I would do it in C++

    size_t size = 500;
    char* dynamicAllocatedString = new char[ size ];
    

    Use same principal for any struct or c++ class.

    0 讨论(0)
  • 2020-11-27 12:26

    In C++, use a vector. It's like an array but you can easily add and remove elements and it will take care of allocating and deallocating memory for you.

    I know the title of the question says C, but you tagged your question with C and C++...

    0 讨论(0)
  • 2020-11-27 12:31

    If you want to dynamically allocate arrays, you can use malloc from stdlib.h.

    If you want to allocate an array of 100 elements using your words struct, try the following:

    words* array = (words*)malloc(sizeof(words) * 100);
    

    The size of the memory that you want to allocate is passed into malloc and then it will return a pointer of type void (void*). In most cases you'll probably want to cast it to the pointer type you desire, which in this case is words*.

    The sizeof keyword is used here to find out the size of the words struct, then that size is multiplied by the number of elements you want to allocate.

    Once you are done, be sure to use free() to free up the heap memory you used in order to prevent memory leaks:

    free(array);
    

    If you want to change the size of the allocated array, you can try to use realloc as others have mentioned, but keep in mind that if you do many reallocs you may end up fragmenting the memory. If you want to dynamically resize the array in order to keep a low memory footprint for your program, it may be better to not do too many reallocs.

    0 讨论(0)
  • 2020-11-27 12:31

    If you want to grow the array dynamically, you should use malloc() to dynamically allocate some fixed amount of memory, and then use realloc() whenever you run out. A common technique is to use an exponential growth function such that you allocate some small fixed amount and then make the array grow by duplicating the allocated amount.

    Some example code would be:

    size = 64; i = 0;
    x = malloc(sizeof(words)*size); /* enough space for 64 words */
    while (read_words()) {
        if (++i > size) {
            size *= 2;
            x = realloc(sizeof(words) * size);
        }
    }
    /* done with x */
    free(x);
    
    0 讨论(0)
提交回复
热议问题