因本人在C语言开发中经常使用到struct结构,且经常与链表配合使用,所以就将这部分代码优化了一下,代码如下[转载请注明出处]
头文件:
/*
* cmDataType.h
*
* Created on: 2011-6-29
* Author: webb
*/
#ifndef CMDATATYPE_H_
#define CMDATATYPE_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef enum _index_bool
{
ITRUE,
IFALSE,
}Ibool;
typedef struct _index_pool
{
void* data;
struct _index_pool* idx_next;
struct _index_pool* idx_prev;
}StructPool;
int struct_size;
/*
初始化StructPool,使用StructPool结构前必须调用
分配StructPool所占内存空间
*/
void init_struct_pool(StructPool *ipool, int data_size);
/*
在指定位置插入一个结构体,并返回其首地址
参数定义:
ipool 当前所使用的结构体池首地址
flag 插入的标志,可随意在某个结构体之后、之前插入
if_next_or_prev 插入到标志之前或之后
*/
void** insert_struct_pool(StructPool *ipool,void** flag,Ibool if_next_or_prev);
/*
获取指定位置的结构体首地址
参数定义:
ipool 当前所使用的结构体池首地址
data 获取标志,可获取此标记之前、之后的结构题首地址
if_next_or_prev 获取标志之前或之后
*/
void** get_struct_pool_data(StructPool *ipool,void** data,Ibool if_next_or_prev);
/*
释放某一个结构体所占内存空间
参数定义:
ipool 当前所使用的结构体池首地址
flag 要释放的结构题首地址
*/
void free_pool_node(StructPool *ipool,void** flag);
/*
销毁ipool结构体池中所有的结构体
调用此函数之后,ipool已不可用,若要继续使用则需要重新调用初始化函数init_struct_pool
*/
void destory_pool(StructPool *ipool);
#endif /* CMDATATYPE_H_ */
主文件:
/*
* csMain.c
*
* Created on: 2011-6-29
* Author:webb
*/
#include "cmDataType.h"
StructPool* get_node_by_data(StructPool *ipool,void** data)
{
StructPool *ip_temp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=ip_temp;
if(data==NULL)
{
ip_temp = ipool;
}
else
{
ip_temp = (StructPool*)data;
}
free(free_p1);
return ip_temp;
}
void init_struct_pool(StructPool *ipool, int data_size)
{
ipool->idx_prev=ipool;
ipool->idx_next=ipool;
struct_size=data_size;
ipool->data = (void*)malloc(data_size);
ipool->data=NULL;
}
void** insert_struct_pool(StructPool *ipool,void** flag,Ibool if_next_or_prev)
{
StructPool *iflag = (StructPool*)malloc(sizeof(StructPool));
StructPool *inode = (StructPool*)malloc(sizeof(StructPool));
StructPool *itemp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=iflag;
StructPool *free_p2 =itemp;
if(flag==NULL)
{
iflag = ipool;
}
else
{
iflag = get_node_by_data(ipool,flag);
}
if(if_next_or_prev==ITRUE)
{
itemp = iflag->idx_next;
iflag->idx_next=inode;
inode->idx_next=itemp;
if(itemp!=NULL)
itemp->idx_prev=inode;
inode->idx_prev=iflag;
}
else
{
itemp = iflag->idx_prev;
iflag->idx_prev=inode;
inode->idx_prev=itemp;
if(itemp!=NULL)
itemp->idx_next=inode;
inode->idx_next=iflag;
}
free(free_p1);
free(free_p2);
inode->data=(void*)malloc(struct_size);
return &inode->data;
}
void** get_struct_pool_data(StructPool *ipool,void** data,Ibool if_next_or_prev)
{
StructPool *ip_temp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=ip_temp;
if(data==NULL)
{
ip_temp = ipool;
}
else
{
ip_temp = get_node_by_data(ipool,data);
}
free(free_p1);
if(if_next_or_prev==ITRUE)
{
return &ip_temp->idx_next->data;
}
else
{
return &ip_temp->idx_prev->data;
}
}
void free_pool_node(StructPool *ipool,void** flag)
{
if(flag==NULL)
{
return;
}
else
{
StructPool *iflag = (StructPool*)malloc(sizeof(StructPool));
StructPool *inode = (StructPool*)malloc(sizeof(StructPool));
StructPool *itemp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=iflag;
StructPool *free_p2 =itemp;
StructPool *free_p3 =inode;
iflag = get_node_by_data(ipool,flag);
itemp = iflag->idx_next;
inode = iflag->idx_prev;
iflag->idx_next=NULL;
iflag->idx_prev=NULL;
if(itemp!=NULL)
itemp->idx_prev=inode;
if(inode!=NULL)
inode->idx_next=itemp;
free(free_p1);
free(free_p1);
free(free_p1);
free(iflag);
}
}
void destory_pool(StructPool *ipool)
{
StructPool *itemp = (StructPool*)malloc(sizeof(StructPool));
itemp=get_node_by_data(ipool,NULL);
itemp=itemp->idx_next;
while(itemp!=ipool)
{
StructPool *idata = (StructPool*)malloc(sizeof(StructPool));
idata=itemp->idx_next;
free(itemp);
itemp=idata;
}
free(ipool);
}
以上代码分别拷贝到对应文件,编译成动态链接库即可调用其中的接口。
使用示例:
/*
* StructPool仅对外公布指针地址,以便快速查找到对应的StructPool节点,采用此方法减少循环所消耗的资源
* StructPool结构也必须用指针地址才能正常访问
* 使用value将无法正常使用StructPool
* StructPool结构是一个双向循环链表
* */
int main(int argc,char* argv[])
{
typedef struct _test_list
{
int sck;
char caTaskID[40];
}TestList;
void** a,**b,**c,**d;
StructPool index_pool;
/*StructPool结构在初始化之后不允许remalloc,即:一个StructPool只能存储占用内存相同的一类struct结构,否则将导致内存错误*/
init_struct_pool(&index_pool,sizeof(TestList));
TestList* test = (TestList*)malloc(sizeof(TestList));
b=insert_struct_pool(&index_pool,NULL,ITRUE);
test=*b;
test->sck=123;
strcpy(test->caTaskID,"test string");
TestList* test2 = (TestList*)malloc(sizeof(TestList));
c=insert_struct_pool(&index_pool,NULL,ITRUE);
test2=*c;
test2->sck=1234;
strcpy(test2->caTaskID,"test string2");
TestList* test1 = (TestList*)malloc(sizeof(TestList));
TestList* test3 = (TestList*)malloc(sizeof(TestList));
a=get_struct_pool_data(&index_pool,NULL,ITRUE);
test1=*a;
printf("%d\n",test1->sck);
printf("%s\n",test1->caTaskID);
d=get_struct_pool_data(&index_pool,a,ITRUE);
test3=*d;
printf("%d\n",test3->sck);
printf("%s\n",test3->caTaskID);
return 0;
}
打印结果:
1234
test string2
123
test string
头文件:
/*
* cmDataType.h
*
* Created on: 2011-6-29
* Author: webb
*/
#ifndef CMDATATYPE_H_
#define CMDATATYPE_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef enum _index_bool
{
ITRUE,
IFALSE,
}Ibool;
typedef struct _index_pool
{
void* data;
struct _index_pool* idx_next;
struct _index_pool* idx_prev;
}StructPool;
int struct_size;
/*
初始化StructPool,使用StructPool结构前必须调用
分配StructPool所占内存空间
*/
void init_struct_pool(StructPool *ipool, int data_size);
/*
在指定位置插入一个结构体,并返回其首地址
参数定义:
ipool 当前所使用的结构体池首地址
flag 插入的标志,可随意在某个结构体之后、之前插入
if_next_or_prev 插入到标志之前或之后
*/
void** insert_struct_pool(StructPool *ipool,void** flag,Ibool if_next_or_prev);
/*
获取指定位置的结构体首地址
参数定义:
ipool 当前所使用的结构体池首地址
data 获取标志,可获取此标记之前、之后的结构题首地址
if_next_or_prev 获取标志之前或之后
*/
void** get_struct_pool_data(StructPool *ipool,void** data,Ibool if_next_or_prev);
/*
释放某一个结构体所占内存空间
参数定义:
ipool 当前所使用的结构体池首地址
flag 要释放的结构题首地址
*/
void free_pool_node(StructPool *ipool,void** flag);
/*
销毁ipool结构体池中所有的结构体
调用此函数之后,ipool已不可用,若要继续使用则需要重新调用初始化函数init_struct_pool
*/
void destory_pool(StructPool *ipool);
#endif /* CMDATATYPE_H_ */
主文件:
/*
* csMain.c
*
* Created on: 2011-6-29
* Author:webb
*/
#include "cmDataType.h"
StructPool* get_node_by_data(StructPool *ipool,void** data)
{
StructPool *ip_temp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=ip_temp;
if(data==NULL)
{
ip_temp = ipool;
}
else
{
ip_temp = (StructPool*)data;
}
free(free_p1);
return ip_temp;
}
void init_struct_pool(StructPool *ipool, int data_size)
{
ipool->idx_prev=ipool;
ipool->idx_next=ipool;
struct_size=data_size;
ipool->data = (void*)malloc(data_size);
ipool->data=NULL;
}
void** insert_struct_pool(StructPool *ipool,void** flag,Ibool if_next_or_prev)
{
StructPool *iflag = (StructPool*)malloc(sizeof(StructPool));
StructPool *inode = (StructPool*)malloc(sizeof(StructPool));
StructPool *itemp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=iflag;
StructPool *free_p2 =itemp;
if(flag==NULL)
{
iflag = ipool;
}
else
{
iflag = get_node_by_data(ipool,flag);
}
if(if_next_or_prev==ITRUE)
{
itemp = iflag->idx_next;
iflag->idx_next=inode;
inode->idx_next=itemp;
if(itemp!=NULL)
itemp->idx_prev=inode;
inode->idx_prev=iflag;
}
else
{
itemp = iflag->idx_prev;
iflag->idx_prev=inode;
inode->idx_prev=itemp;
if(itemp!=NULL)
itemp->idx_next=inode;
inode->idx_next=iflag;
}
free(free_p1);
free(free_p2);
inode->data=(void*)malloc(struct_size);
return &inode->data;
}
void** get_struct_pool_data(StructPool *ipool,void** data,Ibool if_next_or_prev)
{
StructPool *ip_temp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=ip_temp;
if(data==NULL)
{
ip_temp = ipool;
}
else
{
ip_temp = get_node_by_data(ipool,data);
}
free(free_p1);
if(if_next_or_prev==ITRUE)
{
return &ip_temp->idx_next->data;
}
else
{
return &ip_temp->idx_prev->data;
}
}
void free_pool_node(StructPool *ipool,void** flag)
{
if(flag==NULL)
{
return;
}
else
{
StructPool *iflag = (StructPool*)malloc(sizeof(StructPool));
StructPool *inode = (StructPool*)malloc(sizeof(StructPool));
StructPool *itemp = (StructPool*)malloc(sizeof(StructPool));
StructPool *free_p1=iflag;
StructPool *free_p2 =itemp;
StructPool *free_p3 =inode;
iflag = get_node_by_data(ipool,flag);
itemp = iflag->idx_next;
inode = iflag->idx_prev;
iflag->idx_next=NULL;
iflag->idx_prev=NULL;
if(itemp!=NULL)
itemp->idx_prev=inode;
if(inode!=NULL)
inode->idx_next=itemp;
free(free_p1);
free(free_p1);
free(free_p1);
free(iflag);
}
}
void destory_pool(StructPool *ipool)
{
StructPool *itemp = (StructPool*)malloc(sizeof(StructPool));
itemp=get_node_by_data(ipool,NULL);
itemp=itemp->idx_next;
while(itemp!=ipool)
{
StructPool *idata = (StructPool*)malloc(sizeof(StructPool));
idata=itemp->idx_next;
free(itemp);
itemp=idata;
}
free(ipool);
}
以上代码分别拷贝到对应文件,编译成动态链接库即可调用其中的接口。
使用示例:
/*
* StructPool仅对外公布指针地址,以便快速查找到对应的StructPool节点,采用此方法减少循环所消耗的资源
* StructPool结构也必须用指针地址才能正常访问
* 使用value将无法正常使用StructPool
* StructPool结构是一个双向循环链表
* */
int main(int argc,char* argv[])
{
typedef struct _test_list
{
int sck;
char caTaskID[40];
}TestList;
void** a,**b,**c,**d;
StructPool index_pool;
/*StructPool结构在初始化之后不允许remalloc,即:一个StructPool只能存储占用内存相同的一类struct结构,否则将导致内存错误*/
init_struct_pool(&index_pool,sizeof(TestList));
TestList* test = (TestList*)malloc(sizeof(TestList));
b=insert_struct_pool(&index_pool,NULL,ITRUE);
test=*b;
test->sck=123;
strcpy(test->caTaskID,"test string");
TestList* test2 = (TestList*)malloc(sizeof(TestList));
c=insert_struct_pool(&index_pool,NULL,ITRUE);
test2=*c;
test2->sck=1234;
strcpy(test2->caTaskID,"test string2");
TestList* test1 = (TestList*)malloc(sizeof(TestList));
TestList* test3 = (TestList*)malloc(sizeof(TestList));
a=get_struct_pool_data(&index_pool,NULL,ITRUE);
test1=*a;
printf("%d\n",test1->sck);
printf("%s\n",test1->caTaskID);
d=get_struct_pool_data(&index_pool,a,ITRUE);
test3=*d;
printf("%d\n",test3->sck);
printf("%s\n",test3->caTaskID);
return 0;
}
打印结果:
1234
test string2
123
test string