zoukankan      html  css  js  c++  java
  • 柔性数组的结构如何只能堆上生成

    柔性数组是C99的扩展,简而言之就是一个在struct结构里的标识占位符(不占结构struct的空间)。

    声明

    typedef struct zero_array
    {
    size_t len;
    void * array[0];
    }zero_array_t;


    大小

    可以用sizeof 看看其大小

    printf("%d\n",sizeof(zero_array_t));//Debian IA 32 下输出4

    可以看到其array并没有占用空间。

    申请空间

    zero_array_t *ptr = (zero_array_t *)malloc(sizeof(zero_array_t)+sizeof(void *)*len);

    zero_array_t 后面跟着一块len的数组,内存布局有兴趣的同学会画一下。

    引用

    柔性数组是特殊的数组,可以类似数组的方式引用。

    printf("addr = %p\t",ptr->array[i]);


    释放

    由于分配是柔性数组的内存与结构体(相当于头部)一块分配的(一个malloc),所以只需要一个free即可。

    void zero_array_free(zero_array_t *ptr)
    {
    free(ptr);
    }

    柔性数组与指针

    由于指针与数组的想通之处,其实也有如下的实现

    typedef struct pointer_array
    {
    size_t len;
    void * array;
    }pointer_array_t;

    柔性数组相对指针的实现来说有两个优点

    1)可以看到指针是占用空间的,可以测得sizeof(pointer_array_t) ==8 ;

    2)给pointer_array_t 的array需要一次malloc申请,释放也得单独free释放。

    接下来的问题

    ps:写这篇文字的目的是由于调试了一天的bug,发现bug与柔性数组相关。通过栈上分配变量内存,没有给结构体的柔性数组分配内存。

    于是就思考如何强制某些柔性数组只能通过堆上分配内存。

    我的第一想法为通过sizeof来判断array的大小,但失败了。

    因为sizeof是编译时计算的,在编译期间(ptr->array) == 0;

    不知道各位筒子有什么好的方法!

    我的测试代码如下。

    View Code
    #include <stdlib.h>
    #include <stdio.h>
    #include <memory.h>
    #include <assert.h>
    typedef struct zero_array
    {
    size_t len;
    void * array[0];
    }zero_array_t;

    void zero_array_init(zero_array_t *ptr,size_t len)
    {
    //assert(ptr && sizeof(ptr->array));
    assert(ptr && (ptr->array));
    ptr->len = len;
    memset(ptr->array,len,0);
    }

    zero_array_t * zero_array_new(size_t len)
    {
    zero_array_t *ptr = \
    (zero_array_t *)malloc(sizeof(zero_array_t)+sizeof(void *)*len);
    if(ptr)
    zero_array_init(ptr,len);
    return ptr;
    }
    void zero_array_free(zero_array_t *ptr)
    {
    free(ptr);
    }
    void zero_array_printf(zero_array_t *ptr)
    {
    assert(ptr);
    printf("len = %d\n",ptr->len);
    int i = 0 ;
    for(; i < ptr->len; ++i)
    {
    printf("addr = %p\t",ptr->array[i]);
    if(!(i % 5))
    putchar('\n');

    }
    putchar('\n');
    }
    int
    main ( int argc, char *argv[] )
    {
    //通过new生成的
    zero_array_t *new_zero = zero_array_new(10);
    zero_array_printf(new_zero);
    printf("%d\n",sizeof(zero_array_t));
    //通过非new
    zero_array_t nonew_zero;
    zero_array_init(&nonew_zero,10);
    zero_array_printf(&nonew_zero);


    return EXIT_SUCCESS;
    } /* ---------- end of function main ---------- */



  • 相关阅读:
    记一次擦窗机器人项目的拯救
    基于超声波的四轴定高控制简析
    秋夜
    还能再来过?
    机器人设计之一简单机械设计
    管理之殇
    C++11笔记<一>
    Android开发的菜鸟小记
    程序员客栈与DaoCloud这两家企业联手后,运维工程师要失业了!
    关爱码农成长:关于写代码二三事
  • 原文地址:https://www.cnblogs.com/westfly/p/2408488.html
Copyright © 2011-2022 走看看