openssl之stack学习

来源:互联网 发布:心内事无人知谐音歌词 编辑:程序博客网 时间:2024/05/19 22:01

opensll中实现了很多的数据结构,借学习openssl源码来复习数据结构。源码在crypto\stack中。先来分析一下其中实现的源码中结构体定义和一些函数。参考了赵春平老师的Openssl编程

typedef struct stack_st{int num;//存在的节点数char **data;//由于不知道要存储数据的类型,存放数据的地址。类似C++的模板的功能int sorted;//是否有序int num_alloc;//申请的节点数int (*comp)(const char * const *, const char * const *); //函数指针,存储类型的比较函数} STACK;
我对源码的部分进行一点修改,主要把OPENSSL_realloc,OBJ_bsearch_ex等函数改成C标准库中函数,这样可以没安装openssl的情况下,测试代码。下面是几个主要函数。

/*********************************************************函数功能:创建一个stack,并初始化*函数参数:要存储类型的比较函数*函数返回值:成功,则返回创建的STACK对象,失败则返回NULL*******************************************************/STACK *sk_new(int (*c)(const char * const *, const char * const *)){STACK *ret;int i;if ((ret=(STACK *)malloc(sizeof(STACK))) == NULL)goto err;//data相当于是一个指针数据,数组的每个成员是一个指向char*的指针if ((ret->data=(char **)malloc(sizeof(char *)*MIN_NODES)) == NULL)goto err;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);err:if(ret)free(ret);return(NULL);}/*********************************************************函数功能:创建一个stack,并初始化*函数参数:st即要操作的栈;data即为要插入数据的地址;loc即要插入的位置*函数返回值:成功,则返回节点数目,失败则返回0*******************************************************/int sk_insert(STACK *st, char *data, int loc){char **s;if(st == NULL) return 0;if (st->num_alloc <= st->num+1)//首先判断已经申请的节点数是否小于已经存在的节点数+1,是,则扩大2倍,realloc{//注意realloc函数,申请的空间要大于原来的空间,否则数据丢失。申请成功则释放之前的空间,返回成功的内存地址s=(char **)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;//相当于把data的数据从loc开始向后移动一个位置,空出loc位置,具体功能同#ifdef undef 和#endif中的memmove操作f=(char **)st->data;t=(char **)&(st->data[1]);for (i=st->num; i>=loc; i--)t[i]=f[i];#ifdef undef /* no memmove on sunos :-( */memmove( (char *)&(st->data[loc+1]),(char *)&(st->data[loc]),sizeof(char *)*(st->num-loc));#endifst->data[loc]=data;//将地址插入}st->num++;//节点数加1st->sorted=0;return(st->num);}/*函数功能:删除p所指向的内容*/char *sk_delete_ptr(STACK *st, char *p){int i;for (i=0; i<st->num; i++)//线性查找if (st->data[i] == p)return(sk_delete(st,i));return(NULL);}
下面是测试函数的main函数:

#include <stdio.h>#include "stack.h"#include <stdlib.h>#include <string.h>typedefstructStudent_st{char*name;intage;char*otherInfo;}Student;Student *Student_Malloc(){Student *a=(Student*)malloc(sizeof(Student));a->name=(char*)malloc(20);strcpy(a->name,"zcp");a->otherInfo=(char *)malloc(20);strcpy(a->otherInfo,"no info");return a;}voidStudent_Free(Student *a){free(a->name);free(a->otherInfo);free(a);}staticint Student_cmp(Student *a,Student *b){intret;ret=strcmp(*(char**)a->name,*(char**)b->name);return ret;}intmain(){STACK*snew;Student*s1,*one;int i,num; snew=sk_new((int(*)(const char *const * ,const char *const * ))Student_cmp);s1=Student_Malloc();s1->age=20;strcpy(s1->name,"xxx");strcpy(s1->otherInfo,"nickname");sk_push(snew,(char *)s1);s1=Student_Malloc();s1->age=22;strcpy(s1->name,"bbbu");strcpy(s1->otherInfo,"nickname");sk_push(snew,(char *)s1);s1=Student_Malloc();s1->age=24;strcpy(s1->name,"jack");strcpy(s1->otherInfo,"nickname");sk_push(snew,(char *)s1);s1=Student_Malloc();s1->age=22;strcpy(s1->name,"tom");strcpy(s1->otherInfo,"nickname");sk_push(snew,(char *)s1);printf("Before FInd*********************************\n");num=sk_num(snew);for(i=0;i<num;i++){one=(Student*)sk_value(snew,i);printf("student name :%s\n",one->name);printf("sutdentage  :%d\n",one->age);printf("student otherinfo :%s\n\n\n",one->otherInfo);}i=sk_find(snew,(char*)s1);printf("\n\ni=%d",i);printf("After FInd*********************************\n");num=sk_num(snew);for(i=0;i<num;i++){one=(Student*)sk_value(snew,i);printf("student name :%s\n",one->name);printf("sutdentage  :%d\n",one->age);printf("student otherinfo :%s\n\n\n",one->otherInfo);}sk_pop_free(snew,(void(*)(void*))Student_Free);return 0;}
发现一个问题,如果查找,则破坏了之前的栈结构。不知道这样实现的用处。