`
totoxian
  • 浏览: 1038225 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

openssl中的STACK操作实现了一个自动增加的堆栈

 
阅读更多

利用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更能有效组织同类型数据,并且代表了一种更高层次的资源分配,通过这个数据结构可以理解数组和指针的区别,可以得到一种和谭浩强不同的一种理解内存构造的方式。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics