• GNC中“零数组”用法的体会


    struct test1

    {

       int a;

       int *b;

    };

    struct test2

    {

       int a;

       int b[0];

    };

    struct test3

    {

       int a;

       int b[1];

    };

    长度为0的数组在标准c和c++中是不允许的,如果使用长度为0的数组,编译时会产生错误,提示数组长度不能为0。但在GNU C中,这种用法却是合法的。它的最典型的用法就是位于数组中的最后一项,如上面test2所示,这样做主要是为了方便内存缓冲区的管理。对上面3种定义方法进行比较:

    1.对于test1,数组用指针表示,那么在分配内存时,需采用两步:

    首先,需为结构体分配一块内存空间;

    其次再为结构体中的成员变量分配内存空间。

    这样两次分配的内存是不连续的,需要分别对其进行管理。释放时也是一样的,需要单独释放指针,再释放结构体。

    2.对于test2,数组用零数组表示,在分配内存空间时,能够一次性分配内存空间(见下例),释放时也是一样,只需要一次一起释放。

    3.对于test3,数组用用标准数组方式,这样在分配和释放内存空间时也能一次性完成。

    通过以上比较或许看不出零数组有什么特别,可以想一下:如果数组在后续中不一定能用到,test3不管怎样都分配了空间,test1用到时分配和释放都要多一步且至少已经占用了4byte的空间(int的空间),而test2形式就灵活得多,这样一比,或许就能看出零数组的一点好处了。

    或许有的人会说用数组就不用分别分配内存空间了,但可以想一想,

    完整示例(测试环境为VS2010):

    #include <stdio.h>

    #include<stdlib.h>

    #include<malloc.h>

    #define LENGTH 10

    struct test1

    {

       int a;

       int *b;

    };

    struct test2

    {

       int a;

       int b[0];

    };

    struct test3

    {

       int a;

       int b[1];

    };

    int main(int argc,char **argv)

    {

       struct test1 *var1;

       struct test2 *var2;

       struct test3 *var3;

       int i;

       printf("the length of struct test1:%d ",sizeof(struct test1));

       printf("the length of struct test2:%d ",sizeof(struct test2));

       printf("the length of struct test3:%d ",sizeof(struct test3));

       var1=(struct test1*)malloc(sizeof(struct test1));

       var1->a=1;

       var1->b=(int *)malloc(sizeof(int));

       *var1->b=1;

       printf(" var1->a=%d,*(var1->b)=%d ",var1->a,*var1->b);

       var2=(struct test2*)malloc(sizeof(struct test2)+sizeof(int)*LENGTH);  //l零数组现在包含10个元素。

       var2->a=2;

       printf(" var2->a=%d ",var2->a);

       for(i=0;i<LENGTH;i++)

       {

          var2->b[i]=i;

          printf("var2->b[i]=%d ",var2->b[i]);

       }

       printf(" ");

       var3=(struct test3*)malloc(sizeof(struct test3));

       var3->a=3;

       (var3->b)[0]=3;

       printf("var3->a=%d,(var3->b)[0]=%d ",var3->a,(var3->b)[0]);

       free(var1->b);  //先free指针

       free(var1);        //再free结构体

       free(var2);

       free(var3);

       system("pause");

       return 0;

    }

    本文灵感来自“拾月彷徨”的这篇博客:http://my.oschina.net/u/176416/blog/33054

  • 相关阅读:
    VC++使用socket进行TCP、UDP通信实例总结
    [Android Pro] 调用系统相机和图库,裁剪图片
    [Android Pro] 查看 keystore文件的签名信息 和 检查apk文件中的签名信息
    [Android 新特性] 谷歌发布Android Studio开发工具1.0正式版(组图) 2014-12-09 09:35:40
    [Android 新特性] 有史来最大改变 Android 5.0十大新特性
    [Android Pro] service中显示一个dialog 或者通过windowmanage显示view
    [Android Pro] 通过Android trace文件分析死锁ANR
    [Android Memory] Android 的 StrictMode
    [Android Memory] Android性能测试小工具Emmagee
    [Android Memory] Android内存管理、监测剖析
  • 原文地址:https://www.cnblogs.com/haisence/p/3650321.html
Copyright © 2020-2023  润新知