フレキシブル配列の使用


  • フレキシブル配列
  • フレキシブル配列の特徴
  • フレキシブル配列の使用
  • フレキシブル配列の利点

  • フレキシブル配列
    c 99では、構造体の最後のメンバーについて、最後のメンバーが未知のサイズの配列であることを許可することができ、このような配列をフレキシブル配列と呼ぶ.
    typedef struct st_type
    {
        int i;
        int a[0];
    }type_a;

    一部のコンパイラでは、このような書き方が間違っています.次の形式に書き換えることができます.
    typedef struct st_type
    {
        int i;
        int a[];
    }type_a;

    フレキシブル配列の特徴
  • 構造体のフレキシブル配列メンバーの前には、少なくとも1つのタイプのメンバーが含まれなければならない.
  • sizeofが返す構造体の大きさは、フレキシブル配列の大きさを含まない.
  • フレキシブル配列メンバーを含む構造体のサイズはmalloc関数でメモリを動的に割り当て、フレキシブル配列の所望のサイズに適応するために、割り当てられたメモリのサイズは構造体のサイズより大きいべきである.

  • 例:
    typedef struct st_type
    {
        int i;
        int a[0];
    }type_a;
    printf("%d",sizeof(type_a));//4

    フレキシブル配列の使用
    int i=0;
    type_a *p=(type_a *)malloc(sizeof(type_a)+100*sizeof(int));
    p->i=100;
    for(i=0;i<100;i++)
    {
    p->a[i]=i;
    }
    free(p);

    このようなフレキシブル配列メンバーaは、100個の整数要素を得た連続空間に相当する.
    フレキシブル配列の利点
    上記の構造体は、
    typedef struct st_type
    {
    int i;
    int *p_a;
    }type_a;
    
    type_a *p=(type_a *)malloc(sizeof(type_a));
    p->i=100;
    p->p_a=(int *)malloc(p->i*sizeof(int));
    for(i=0;i<100;i++)
    {
    p->p_a[i]=i;
    }
    
    free(p->p_a);
    p->p_a=NULL;
    
    free(p);
    p=NULL;

    上記の2つの方法は同じ機能を達成することができますが、第1のフレキシブル配列を使用する実現には2つの利点があります.第1の利点は、メモリの解放を容易にすることです.もし私たちのコードが他の人に使用される関数であれば、あなたは関数の中で2回のメモリ割り当てを行い、構造体全体をユーザーに返します.ユーザがfreeを呼び出すと構造体を解放することができるが、ユーザはこの構造体内のメンバーもfreeを必要とすることを知らないので、ユーザがこのことを発見することを期待することはできない.したがって、構造体のメモリとそのメンバーが必要とするメモリを一度に割り当てて、ユーザーに構造体ポインタを返すと、ユーザーはfreeを1回してすべてのメモリを解放することができます.2つ目の利点は、アクセス速度が向上することです.継続的なメモリは、アクセス速度を向上させ、メモリの破片を減らすのに役立ちます.