柔性数组

1、什么是柔性数组

柔性数组是C99标准特性,GNU的GCC编译器也允许这样的写法。具体为在一个结构体最后可以加上一个类似于char str[0];的声明,代表可变长的一个数组,str并不是一个指针,而是代表着str这个数组在其结构体中的偏移量,这个在下面的代码中可以看出来。在使用的时候动态分配内存,使用完之后随手释放。

2、测试代码的编写

#include <stdio.h> 
#include <stdlib.h>
#include <wchar.h>

struct p_test
{
    int age;
    int height;
    char name[0];   //如果放在中间或者前面的话,则name代表的偏移量与紧跟其后的变量地址是一样的,那就造成了变量重叠的后果
}__attribute ((packed));    //禁止编译器进行字节对齐

struct p_test1
{
    int age;
    int height;
    char *name;
}__attribute ((packed));

struct p_test2
{
    int age;
    int height;
    char name[3];
}__attribute ((packed));

struct p_test3
{
    int age;
    int height;
    char name[];
}__attribute ((packed));    //不进行对齐

int main(int argv, char *argc[])
{
    struct p_test *example;

    example = (struct p_test *)malloc(sizeof(struct p_test) + 20);

    example->age = 30;
    example->height = 176;

    memcpy(example->name, "job geo", 8);

    printf("age = %d\nheight = %d\nname = %s\n", example->age, example->height, example->name);
    printf("sizeof p_test : %d\n", sizeof(struct p_test));
    printf("sizeof p_test1 : %d\n", sizeof(struct p_test1));
    printf("sizeof p_test2 : %d\n", sizeof(struct p_test2));
    printf("sizeof p_test3 : %d\n", sizeof(struct p_test3));

    free(example);

    return 0;
}

打印结果

   
   
   
   
age = 30 height = 176 name = job geo sizeof p_test : 8 sizeof p_test1 : 12 sizeof p_test2 : 11 sizeof p_test3 : 8 --------------------------------

可以看到,上面的p_test1与p_test2结构体的长度都是12,因为p_test1里面的char *name;中的name是一个指针,既然是指针,那么在内存当中就会占用空间(而p_test里面的name却不占用空间),并且其地址不一定是与结构体上面的成员紧密相连,这样就会造成内存的碎片化。并且使用name的时候需要对其分配空间,在释放的时候需要先把name指向的内容释放,并且把其结构体也释放掉,而柔性数组则是一次性分配完毕,一次性释放完毕
形如char name[3];这样的定义在结构体初始化的时候就指定了长度,而实际使用中如果我们用不到那么多的空间就会造成空间的浪费,所以不如柔性数组来的有效与便捷

3、指针与数组名的区别
指针是一个变量,是占用内存的。而数组的名并不是一个变量,其不占用内存空间,仅代表一个偏移地址

你可能感兴趣的:(内存,C语言,结构,柔性数组)