Static allocation of opaque data types

前端 未结 9 1074
天涯浪人
天涯浪人 2020-11-27 13:50

Very often malloc() is absolutely not allowed when programming for embedded systems. Most of the time I\'m pretty able to deal with this, but one thing irritates me: it keep

9条回答
  •  暖寄归人
    2020-11-27 14:24

    I faced a similar problem in implementing a data structure in which the header of the data structure, which is opaque, holds all the various data that needs to be carried over from operation to operation.

    Since re-initialization might cause a memory leak, I wanted to make sure that data structure implementation itself never actually overwrite a point to heap allocated memory.

    What I did is the following:

    /** 
     * In order to allow the client to place the data structure header on the
     * stack we need data structure header size. [1/4]
    **/
    #define CT_HEADER_SIZE  ( (sizeof(void*) * 2)           \
                            + (sizeof(int) * 2)             \
                            + (sizeof(unsigned long) * 1)   \
                            )
    
    /**
     * After the size has been produced, a type which is a size *alias* of the
     * header can be created. [2/4] 
    **/        
    struct header { char h_sz[CT_HEADER_SIZE]; };
    typedef struct header data_structure_header;
    
    /* In all the public interfaces the size alias is used. [3/4] */
    bool ds_init_new(data_structure_header *ds /* , ...*/);
    

    In the implementation file:

    struct imp_header {
        void *ptr1, 
             *ptr2;
        int  i, 
             max;
        unsigned long total;
    };
    
    /* implementation proper */
    static bool imp_init_new(struct imp_header *head /* , ...*/)
    {
        return false; 
    }
    
    /* public interface */
    bool ds_init_new(data_structure_header *ds /* , ...*/) 
    {
        int i;
    
        /* only accept a zero init'ed header */
        for(i = 0; i < CT_HEADER_SIZE; ++i) {
            if(ds->h_sz[i] != 0) {
                return false;
            }
        }
    
        /* just in case we forgot something */
        assert(sizeof(data_structure_header) == sizeof(struct imp_header));
    
        /* Explicit conversion is used from the public interface to the
         * implementation proper.  [4/4]
         */
        return imp_init_new( (struct imp_header *)ds /* , ...*/); 
    }
    

    client side:

    int foo() 
    {
        data_structure_header ds = { 0 };
    
        ds_init_new(&ds /*, ...*/);
    }
    

提交回复
热议问题