flexible array flexible array, indefinite data structure details-Alibaba Cloud Developer Community

Flexible array, which is a relatively novel term for me, can be seen when learning the implementation of jump tables. How elegant it is behind such a nice name.

The unique and confusing part of the name of flexible array lies in the word "flexible. An array defined in C/C ++ is a fixed-length data structure. The most commonly used definitions are as follows:

int arr[100];

in the preceding code arrthe length of the array is known. We call the preceding statement a declarative statement. Because the length of the number Group has been determined at compile time, I have invented a word to call this kind of array for the time being-" rigid "Array (Declaration, this word is my imagination, there is no such statement).

You may say: wait, C/C ++ can not be passed during the operation period mallocis it called to create a dynamic array? Yes, flexible arrays are exactly needed mallocto achieve, its flexibility is also reflected in this place.

Routine first

let's first take a look at what the flexible array is used?

flexible array member (flexible array member) is also called a scalable array member. This structure is generated and the dynamic structure is removed. In daily programming, it is sometimes necessary to store a dynamic string (or other data types) in the structure. In general, define a pointer member in the structure, this pointer member points to the dynamic memory space where the string is located.

In general, if you want to use memory efficiently, it is a waste of time to define static arrays inside the structure. In fact, the idea of flexible array is the same as that of dynamic array.

Prerequisite knowledge

  • incomplete Type

    in C/C ++, incomplete types are defined as follows: incomplete types are lack of sufficient information to describe the type of a complete object, take the definition/declaration of an array as an example.
// 一个为知长度的数组属于不完整类型 // 这个语句属于声明语句,不是定义语句 extern int a[]; // 这样的语句是错误的, extern关键字不能去掉 // int a[] // 不完整类型的数组需要补充完整才能使用 // 下面的语句是声明语句(定义+初始化) int a[] = {10, 20};
  • Structure

    if you see this title, you may say, what? Do you need to supplement the structure? If you are familiar with structures and memory, skip this section and read the summary of this paragraph, which is helpful for the following explanation of flexible arrays.

The memory alignment is beyond the content discussed in the article. What do I want to talk about? Let's look at the following code

#include<stdio.h> struct test{ int i; char *p; }; intmain(void){ struct test t; printf("t:\t%p\n", &t); printf("t.i:\t%p\n", &(t.i)); printf("t.p:\t%p\n", &(t.p)); }

we see t.iaddress and tthe address is the same. t.pThe address is (&t + 0x8), the offset address 0 × 8 is the address where member p is hard code given by the compiler at compile time.

Summary : no matter what the instance of the structure is, the access to its members is the address of the instance plus the member offset. This offset is hard code of the compiler and is related to factors such as memory alignment.

The call came out

let's review that a flexible array is used to store a dynamic string in a structure. In fact, we can do the same without flexible arrays: define a method in the structure and dynamically point the pointer to the dynamic array in the method.

#include<cstring> #include<cstdlib> #include<cstdio> struct Test{ int a; char *p; voidset_str(constchar *str){ int len = std::strlen(str); if(len <=0) return; p = (char*)std::malloc((len+1)*sizeof(char)); std::strcpy(p, str); p[len] = '\0'; } }; intmain(){ const char copy_str[] = "Hello World"; Test t; t.set_str(copy_str); printf("Content:\n"); printf("t.p:\t%s\n", t.p); printf("Address:\n"); printf("t.p\t %p\n", t.p); printf("&t.p\t %p\n", &(t.p)); }

We can see that the above code can indeed achieve the desired results. Let's take a look at the pointer p and the starting address of the array. We can see that the memory block of the dynamic array and the memory of the string are two different pieces of memory. It is torturing programmers. When we analyze objects, we need to explicitly face the pointer in the destructor. pRelease the referenced memory. Otherwise, memory leakage may occur.

How do flexible arrays work? Return to the above structure

struct Test{ int a; char *p; };

if you want to connect a string with a structure, you can release the memory of the string by the way when you release the memory. Take a look at the following code

// 使用上面的结构体Test const str copy_str[] = "Hello World"; int len = std::strlen(copy_str); // 申请连续的空间 Test *p_test = (Test*)std::malloc(sizeof(Test)+(len+1)*sizeof(char)); // 复制数组 std::strcpy(p_test+1, copy_str); ((char*)(p_test+1))[len] = '\0';

at the beginning of this dependency, you will find char *pit becomes unnecessary. We can use statements completely. (char*)(p_test+1)To obtain the string address.

Smart programmers don't want to be fooled by such ugly code. They think it would be great if they can find a way to reference strings directly without occupying the space of structures. Those that meet this condition should be non-object symbolic address . Recall what was said above incomplete Type , starting with a symbolic address. Put a length 0 however, the C/C ++ standard does not define an array with a length of 0. Standard not allowed? Compiler manufacturers can develop their own. Some compilers use 0-length arrays as their non-standard extensions.

struct flexible_t{ int a; double b; char c[0]; }; 

cIt is called flexible array member. I think it is also possible to translate it into flexible array idioms. The p_test->cis the first address of the array, no longer need the original ugly code.

This code structure is so common that the standard is immediately supported. A flexible member array is included in the C99 standard. Do you remember the incomplete type mentioned above? C99 uses the incomplete type to implement flexible array members. Why use incomplete types? Tell me about my understanding.

int a[] = {10, 20}; 

Seeing this statement, we found that a[]in fact, it is an array mark, which is not of the complete type. Due to the assignment statement, the size of the array is determined at compile time, which is a complete array type. In the structure, it is convenient to use the incomplete type to indicate the dynamic array when running.

The definition of C99 standard is as follows:

struct flexible_t{ int a; double b; char c[]; // 不只是char类型,其他类型同样也是可以 }

due to the declaration of memory continuity, flexible array members must be defined at the last of the structure and cannot be unique members. Let's take a look at the entire structure (including the distribution of array memory)

#include<cstring> #include<cstdlib> #include<cstdio> # define new_instance(n) (Felexible*) std::malloc(sizeof(Flexible) + (n+1)*sizeof(char)) struct Flexible{ int a; char p[0]; }; intmain(){ const char copy_str[] = "Hello World"; // 我们使用宏来把创建对象的代码简化 Flexible *flexible_p = new_instance(std::strlen(copy_str)); std::strcpy(flexible_p->p, copy_str); printf("Content:\n"); printf("%s\n", flexible_p->p); printf("Address:\n"); printf("t.p:\t %p\n", flexible_p->p); printf("&t.p:\t %p\n", &(flexible_p->p)); free(flexible_p); }

it can be seen from the running results that the whole structure is continuous, and the way to release the structure is very simple and directly releases the structure pointer.

warning C4200: non-standard extension: Zero-size array in structure/Union

because this is the C99 standard, in ISO C and C ++ specifications are not allowed . Using an array of 0 lengths in vs may result in a warning. However, gcc and clang ++ support C99 in advance, so compiling in Linux without warning

summary

we learned the source and usage of flexible array members. In fact, flexible array members have special usage when implementing jump tables. In Redis SDSflexible array members are also used in data structures and the implementation of jump tables.

 

Selected, One-Stop Store for Enterprise Applications
Support various scenarios to meet companies' needs at different stages of development

Start Building Today with a Free Trial to 50+ Products

Learn and experience the power of Alibaba Cloud.

Sign Up Now