openssl之stack学习

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; idata[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));
#endif
		st->data[loc]=data;//将地址插入
		}
	st->num++;//节点数加1
	st->sorted=0;
	return(st->num);
	}
/*
函数功能:删除p所指向的内容
*/
char *sk_delete_ptr(STACK *st, char *p)
	{
	int i;

	for (i=0; inum; i++)//线性查找
		if (st->data[i] == p)
			return(sk_delete(st,i));
	return(NULL);
	}
下面是测试函数的main函数:

#include 
#include "stack.h"
#include 
#include 

typedef	struct	Student_st
{
	char		*name;
	int		age;
	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;
}

void	Student_Free(Student *a)
{
	free(a->name);
	free(a->otherInfo);
	free(a);
}

static	int Student_cmp(Student *a,Student *b)
{
	int		ret;
	
	ret=strcmp(*(char**)a->name,*(char**)b->name);
	return ret;
}
int	main()
{
	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;iname);
		printf("sutdent	age  :	%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;iname);
		printf("sutdent	age  :	%d\n",one->age);
		printf("student otherinfo :	%s\n\n\n",one->otherInfo);
	}

	sk_pop_free(snew,(void(*)(void*))Student_Free);

	return 0;
}
发现一个问题,如果查找,则破坏了之前的栈结构。不知道这样实现的用处。


你可能感兴趣的:(数据结构和算法)