C Language Flexible Array example detailed _c language

Source: Internet
Author: User
Tags array example array length documentation

In this paper, the concept and usage of flexible array of C language are analyzed, which can be used for reference to further study of C programming. Share to everyone for your reference. Specifically as follows:

In general, the last element in the structure allows an array of unknown size, which is a flexible array. However, the flexible array in the structure must precede at least one other member , and the flexible array member allows the structure to contain a variable size array, and the sizeof returns the structure size excluding the memory of the flexible array. Structures containing flexible array members are dynamically allocated in memory using the malloc function, and the allocated memory should be larger than the size of the structure to accommodate the expected size of the flexible array. How exactly does a flexible array work?

Incomplete type

C and C + + are the same for the definition of an incomplete type, and the incomplete type is a type that lacks enough information, such as length, to describe a complete object.

Examples of incomplete types:
A forward declaration is a common, incomplete type

struct test; Test only gives the declaration, does not give a definition

Incomplete data types must be supplemented in some way to enable them to be instantiated. Otherwise, it can only be used to define pointers or references, because the pointer or reference itself is instantiated, not the base and test objects

An array of unknown length also belongs to an incomplete type:

extern int a[];

The extern keyword cannot be removed because the length of the array is unknown and cannot appear as a definition. An array of incomplete types needs to be fully added to use. An array of incomplete types can be completed in several ways, and the initialization of curly braces is one of the ways:

int a[] = {10,20};

Structural body

First of all, we need to know--the so-called variable, in fact, is the memory of the address of a smoke-like name . In a statically compiled program, all variable names are converted to memory addresses at compile time. The machine is not aware of the name we take, only know the address.

So there's the stack memory area, the heap memory area, the static memory area, the constant memory area, and all the variables in our code are put into the memory area beforehand by the compiler.

With the above foundation, let's take a look at the address of the members in the structure. Let's simplify the code first:

struct test{
  int i;
  char *p;
};

In the code above, the I and P pointers in the test structure hold the relative addresses in the C compiler-that is, their address is relative to the instance of struct test. If we have this code:

struct Test T;

Here's an experiment:

#include <stdio.h>
struct test{
  int i;
  char *p;
};
int main (void)
{
  struct test t;
  printf ("%p\n", &t);
  printf ("%p\n", & (T.I));
  printf ("%p\n", & (T.P));
  return 0;
}

Run Result:

As we can see, the address of T.I is the same as the address of T, and T.P's address is 8 more than that of T. Plainly, T.I is actually (&t + 0x0), T.P is actually (&t + 0x8). The offset address of 0x0 and 0x8 is the address that the member I and P were given the compiler to hard code at compile time. So, you know, whatever the instance of the struct is--accessing its members is actually a plus-member offset.

Let's do an experiment here:

#include <stdio.h>
struct test{
  int i;
  Short C;
  char *p;
};
int main (void)
{
  struct test *pt=null;
  printf ("%p\n", & (Pt->i));
  printf ("%p\n", & (Pt->c));
  printf ("%p\n", & (Pt->p));
  return 0;
}

Run Result:

Note: The pt->p offset above is 0x8 rather than 0x6 because the memory is aligned (I'm on a 64-bit system). About the memory alignment, you can refer to this Site C language Memory Alignment example to explain the article.

Flexible array

Flexible array members (flexible array member) are also called Scalable array members, which arise from the need for dynamic structures. In everyday programming, it is sometimes necessary to store a dynamic length string in a structure, in general by defining a pointer member in the structure body that points to the dynamic memory space in which the string resides, for example:

struct s_test
{
  int A;
  Double b;
  char* p;
};

P points to a string, which causes the string to be detached from the structure and is not conducive to manipulation. By connecting the strings to the structure, the results are better and can be modified as follows:

Char a[] = "Hello world";
struct S_test *ptest = (struct s_test*) malloc (sizeof (s_test) +streln (a) +1);
strcpy (Ptest+1,a);

Thus, (char*) (PTESTT + 1) is the address of the string "Hello World". At this point P becomes superfluous and can be removed. However, another problem arises: it is inconvenient to always use (char*) (PTESTT + 1). If you can find a way to directly reference the string, and not occupy the space of the structure, it is perfect, the code structure in line with this condition should be a non object symbolic address, the end of the structure of a 0-length array is an excellent solution. However, the C + + standard does not define an array of length 0, so some compilers use 0-length array members as their non-standard extensions, such as:

struct S_TEST2
{
  int A;
  Double b;
  Char c[0];

C is called flexible array members, if the ptest pointed to the dynamic allocation of memory as a whole, C is a dynamic length can change the structure of members, the word "flexible" from this. The length of c is 0, so it does not occupy the space of test, and Ptest->c is the first address of "Hello World", no need to use (char*) (PTESTT + 1) so ugly syntax.

Given the important role that this code structure produces, C99 even puts it in the standard:

As a special case, the "last element of a" structure with more than one named a have array type; This is called a flexible array member.
C99 uses an incomplete type to implement a flexible array member, as in the standard form:

struct s_test
{
 int A;
 Double b;
 Char c[];

C also does not occupy the space of test, only as a symbolic address, and must be the last member of the structure body. Flexible array members can be used not only for character arrays, but also for elements other types of arrays, such as:

struct s_test
{
  int A;
  Double b;
  Float[];
};

First, we need to know that0-length arrays are not allowed in the specifications of ISO C and C + + . That's why compiling under vc++2012 you get a warning: "Arning C4200: A nonstandard extension: An array of 0 sizes in a struct/union."

So why does GCC go through without even a warning? That's because GCC, in order to support C99 's play in advance, makes the "0-length array" legal. About GCC's documentation for this matter here: "Arrays of Length Zero", the documentation gives an example of the complete code as follows:

#include <stdlib.h>
#include <string.h>
struct line {
  int length;
  Char Contents[0]; C99 's play is: Char contents[]; Array length not specified
};
int main () {
  int this_length=10;
  struct line *thisline = (struct line *)
           malloc (sizeof (struct line) + this_length);
  Thisline->length = this_length;
  memset (thisline->contents, ' a ', this_length);
  return 0;
}

The above code means: I want to allocate an indefinite length of an array, so I have a structure, which has two members, one is length, represents the size of the array, one is contents, the contents of the code array. The This_length (length 10) in the back code represents the length of the data that you want to allocate.

I believe that this article on the C programming for everyone to learn the value of a certain reference.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.