OpenSSL中的STACK_OF

来源:互联网 发布:webshell提权 编辑:程序博客网 时间:2024/04/27 13:59
阅读使用OpenSSL的代码,很多地方都遇到了STACK_OF(...),一直不明白是什么意思。下面的文章做了一定的讲解,记在这里,以备查看。
一下内容转自:http://blog.csdn.net/dog250/article/details/5443209
利用STACK_OF宏可以快速实现一个自动增长的堆栈,由于堆栈可以作为一个数组来使用,所以OpenSSL中很多地方都使用了STACK_OF宏来实现大小不固定的数组。

typedef struct stack_st {    int num;      //当前的堆栈元素数量    char **data;  //堆栈元素,其实就是一系列的指针    int sorted;    int num_alloc; //当前的最大容量    int (*comp)(const char * const *, const char * const *);} STACK;#define STACK_OF(type) struct stack_st_##type#define PREDECLARE_STACK_OF(type) STACK_OF(type);#define DECLARE_STACK_OF(type) /STACK_OF(type)         /{             /    STACK stack;     /};//实现一个stack的分配操作STACK *sk_new(int (*c)(const char * const *, const char * const *)){    STACK *ret;    int i;    (STACK *)OPENSSL_malloc(sizeof(STACK)); //分配STACK本身    ret->data=(char **)OPENSSL_malloc(sizeof(char *)*MIN_NODES); //分配堆栈中的指针,最小分配MIN_NODES个    for (i=0; i<MIN_NODES; i++) //初始化        ret->data[i]=NULL;    ret->comp=c;    ret->num_alloc=MIN_NODES;    ret->num=0;    ret->sorted=0;    return(ret);...}//实现了push操作int sk_insert(STACK *st, char *data, int loc){    char **s;    if(st == NULL) return 0;    if (st->num_alloc <= st->num+1) { //如果空间不够了,那么再分配,其实就是增加原来的空间        s=(char **)OPENSSL_realloc((char *)st->data,            (unsigned int)sizeof(char *)*st->num_alloc*2);        if (s == NULL)            return(0);        st->data=s;        st->num_alloc*=2;    }    if ((loc >= (int)st->num) || (loc < 0))        st->data[st->num]=data;    else {        int i;        char **f,**t;        f=(char **)st->data;        t=(char **)&(st->data[1]);        for (i=st->num; i>=loc; i--)            t[i]=f[i];        st->data[loc]=data;    }    st->num++;    st->sorted=0;    return(st->num);}

这个结构主要是为了迎合一些拥有变长字段的结构体,在linux内核中也不乏这样的策略,比如netfilter和路由表等等,这个设计十分符合协议的设计,十分符合拥有定长头和变长数据的数据结构的设计,我十分喜欢,如果说brk是操作系统层次的分配,而malloc是库的分配的话,我宁愿相信这种自动增长的堆栈是一种更加合理的malloc或者更加合理的slab,它比传统的malloc更能有效组织同类型数据,并且代表了一种更高层次的资源分配,通过这个数据结构可以理解数组和指针的区别,可以得到一种和谭浩强不同的理解内存构造的方式。

0 0