Knowledge about those flexible arrays

catalogue

1, What is a flexible array

2, Characteristics of flexible array

  3, Benefits of using flexible arrays

4, What is memory fragmentation

1, What is a flexible array

Perhaps you have never heard of the concept of flexible array, but it does exist. In the C99 standard, the last element in the structure is allowed to be an array of unknown size, which is called a "flexible array" member.

🌝 example

//Writing method 1
struct st_type
{
    int i ;
    int arr[];	//Flexible array member
};

//Writing method 2
struct st_type
{
    int i ;
    int arr[0];	//Flexible array member
};

//For writing method 2: some compilers will report errors and cannot compile

2, Characteristics of flexible array

  • 🛸 Feature 1   : A flexible array member in a structure must be preceded by at least one other member.
struct A
{
    int arr[];	//Flexible array member
    int i;
};
//Errors may be reported. Flexible array members must be preceded by at least one other member
  • 🚅 Feature 2:   The size of this structure returned by sizeof does not include the memory of the flexible array.
struct A
{
    int i ;	//4
    int arr[];
};
int main()
{
    printf("%d\n",sizeof(struct A)); //4
    return 0;
}
  • 🚞 Feature 3:   The structure containing flexible array members uses malloc() function to dynamically allocate memory, and the allocated memory should be larger than the size of the structure to adapt to the expected size of the flexible array
struct st_type
{
    int i ;
    int arr[];
};
int main()
{
    struct st_type* p = (struct st_type*)malloc(sizeof(struct st_type)+10*sizeof(int));
    //It opens up 10 spaces of integer size for array arr
    if( p!= NULL)
    {
        int i = 0;
        for(i = 0;i < 10;i++)
        {
            p->arr[i] = i;
            printf("%d ",p->arr[i]);
        }
        p->i = 100;
        printf("%d\n", p->i);
    }
  	return 0;
}

 

🎨 It opens up 10 spaces of integer size for array arr

  3, Benefits of using flexible arrays

🛍 Examples of using flexible arrays:

struct st_type
{
    int i;
    int arr[];	//Flexible array member
};
int main()
{
    struct st_type* p = (struct st_type*)malloc(sizeof(struct st_type) + 10 * sizeof(int));
    //It opens up 10 spaces of integer size for array arr
    int i = 0;
    if (p != NULL)
    {
        for (i = 0; i < 10; i++)
        {
            //Assign values to flexible array members
            p->arr[i] = i;
            printf("%d ", p->arr[i]);
        }
        p->i = 100;
        printf("%d\n", p->i);
    }
    else
    {
        printf("Development failure\n");
        return -1;
    }
    //Capacity can also be increased when there is not enough space
    struct st_type* ptr = (struct st_type*)realloc(p, sizeof(struct st_type) + 20 * sizeof(int));
    if (ptr == NULL)
    {
        printf("Capacity expansion failed\n");
        return -1;
    }
    else
    {
        p = ptr;	//Assign the address of the augmented space to p
    }
    //use
    for (i = 10; i < 20; i++)
    {
        p->arr[i] = i;
        printf("%d ", p->arr[i]);
    }
    //release
    free(p);
    p = NULL;
    return 0;
}

  💎 For the above, we can also use dynamic array implementation

struct st_type
{
    int i ;	
    int* arr;//Point to a dynamic array	
};
int main()
{
    struct st_type* ps = (struct st_type*)malloc(sizeof(struct st_type));
    ps-> i = 100;
    ps->arr = (int*)malloc(10*sizeof(int));
    int i = 0;
    for(i = 0;i <10;i++)
    {
        ps->arr[i] = i;
        printf("%d ",ps->arr[i]);
    }
    // a. if the space is not enough, the capacity will be increased
    int* ptr = (int*)realloc(ps->arr,20*sizeof(int));
    if(ptr == NULL)
    {
        printf("Capacity expansion failed\n");
        return -1;
    }
    else
    {
        ps->arr = ptr;
    }
    //use
    for(i = 10;i<20;i++)
    {
        ps->arr[i] = i;
        printf("%d ",ps->arr[i]);
    }
    
    //Release!! Pay attention to the release sequence
    free(ps->arr);
    ps->arr = NULL;
    free(ps);
    ps = NULL;
    return 0;
}

👒 be careful!!: First release the dynamically opened array in the structure, and then release the dynamically opened structure  

🤎 The same function can be realized for the above writing method 1 and writing method 2, but the implementation of writing method 1 has two advantages

💦💨 First benefit: easy memory release

If our code is in a function for others, you make a secondary memory allocation in it and return the whole structure to the user. The user can release the structure by calling free, but the user does not know that the members in the structure also need free, so you can't expect the user to find it. Therefore, if we allocate the memory of the structure and the memory required by its members at one time and return a structure pointer to the user, the user can free all the memory once.

💛 Second benefit: it is conducive to access speed

Continuous memory is beneficial to improve access speed and reduce memory fragmentation.

4, What is memory fragmentation

💓 Dynamic allocation will inevitably lead to the problem of memory fragmentation, so what is memory fragmentation? Memory fragmentation, or "fragmented memory", describes all unavailable free memory in a system. These fragments cannot be used because they are responsible for Dynamically allocate memory Distribution of algorithm This problem occurs because these free memories appear in different locations in a small and discontinuous manner. Therefore, the size of this problem depends on the implementation of memory management algorithm.                                                                                 [from Baidu Encyclopedia]

💢 Generally speaking, dynamic space development is random, and the gap between spaces is memory fragments

💥 I hope this article is helpful to you! Welcome big guys to stay for three companies to support!  

Tags: C C++

Posted on Thu, 14 Oct 2021 19:27:25 -0400 by symchicken