Update Array.h

main
po79yr3at 1 year ago
parent 4c81b46c25
commit 4c5713efca

@ -1,251 +1,250 @@
#ifndef ARRAY_INCLUDED #ifndef ARRAY_INCLUDED
#include<assert.h> #include<assert.h>
#include<malloc.h> #include<malloc.h>
#include<stdlib.h> #include<stdlib.h>
#include<string.h> #include<string.h>
/*带有assert的安全分配内存*/ /*带有assert的安全分配内存*/
void *malloc_s(int _size){ void *malloc_s(int _size){
assert(_size > 0); assert(_size > 0);
void *malloc_ptr = malloc(_size); void *malloc_ptr = malloc(_size);
assert(malloc_ptr != NULL); assert(malloc_ptr != NULL);
return malloc_ptr; return malloc_ptr;
} }
/*字符串变量的创建与复制*/ /*字符串变量的创建与复制*/
char *malloc_s_strcpy(const char *const src){ char *malloc_s_strcpy(const char *const src){
//申请char[]时需要多分配几个位置用于存放'\0'结束符 //申请char[]时需要多分配几个位置用于存放'\0'结束符
char *dst = malloc_s(strlen(src)+2); char *dst = malloc_s(strlen(src)+2);
strcpy(dst, src); strcpy(dst, src);
return dst; return dst;
} }
/*MARCO:根据类型安全分配内存*/ /*MARCO:根据类型安全分配内存*/
#define MALLOC_S(TypeName) (TypeName *)(malloc_s(sizeof(TypeName))) #define MALLOC_S(TypeName) (TypeName *)(malloc_s(sizeof(TypeName)))
/*链表单元*/ /*链表单元*/
struct Array_{ struct Array_{
void *p; /*内容数据*/ void *p; /*内容数据*/
struct Array_ *next; struct Array_ *next;
}; };
/*通过单向链表实现的动态数组,需要指定内置数据的类型*/ /*通过单向链表实现的动态数组,需要指定内置数据的类型*/
struct Array{ struct Array{
struct Array_ *front, *back; /*头尾节点*/ struct Array_ *front, *back; /*头尾节点*/
int TypeSize; /*内置类型的大小(不包含动态数据的纯大小)*/ int TypeSize; /*内置类型的大小(不包含动态数据的纯大小)*/
int size; /*总体大小*/ int size; /*总体大小*/
}; };
/*链表初始化*/ /*链表初始化*/
void Array_create(struct Array *a, int ts) void Array_create(struct Array *a, int ts)
{ {
assert("Array_create" && ts > 0); assert("Array_create" && ts > 0);
a->TypeSize = ts; a->TypeSize = ts;
a->size = 0; a->size = 0;
a->back = a->front = NULL; a->back = a->front = NULL;
} }
void Array_release_(struct Array_ *a, struct Array_ *back, void (*rel)(void *)){ void Array_release_(struct Array_ *a, struct Array_ *back, void (*rel)(void *)){
if(a == back) return ; if(a == back) return ;
Array_release_(a->next, back, rel); Array_release_(a->next, back, rel);
rel(a->p); rel(a->p);
free(a->p); free(a->p);
free(a); free(a);
} }
/*释放动态分配的内存,需要指定释放内部动态成员的方法*/ /*释放动态分配的内存,需要指定释放内部动态成员的方法*/
void Array_release(struct Array *a, void (*rel)(void *)){ void Array_release(struct Array *a, void (*rel)(void *)){
Array_release_(a->front, a->back, rel); Array_release_(a->front, a->back, rel);
a->size = 0; a->size = 0;
a->back = a->front = NULL; a->back = a->front = NULL;
} }
/*返回指定位置的Array_*指针 /*返回指定位置的Array_*指针
PAT*/ PAT*/
struct Array_ *Array(struct Array *a, int pos){ struct Array_ *Array(struct Array *a, int pos){
assert("Array[pos]" && pos >= 0 && pos < a->size); assert("Array[pos]" && pos >= 0 && pos < a->size);
struct Array_ *node = a->front; struct Array_ *node = a->front;
for(int i = 0; i < pos; i ++) node = node->next; for(int i = 0; i < pos; i ++) node = node->next;
return node; return node;
} }
/*在pos前插入*/ /*在pos前插入*/
void Array_insert(struct Array *a, void *p, int pos) void Array_insert(struct Array *a, void *p, int pos)
{ {
assert("Array_insert" && pos >= 0 && pos <= a->size); assert("Array_insert" && pos >= 0 && pos <= a->size);
struct Array_ *newNode, *node = a->front; struct Array_ *newNode, *node = a->front;
newNode = MALLOC_S(struct Array_); newNode = MALLOC_S(struct Array_);
newNode->p = malloc_s(a->TypeSize); newNode->p = malloc_s(a->TypeSize);
memcpy(newNode->p, p, a->TypeSize); memcpy(newNode->p, p, a->TypeSize);
if(pos == 0){ if(pos == 0){
newNode->next = a->front; newNode->next = a->front;
a->front = newNode; a->front = newNode;
}else{ }else{
for(int i = 0; i < pos-1; i ++) node = node->next; for(int i = 0; i < pos-1; i ++) node = node->next;
newNode->next = node->next; newNode->next = node->next;
node->next = newNode; node->next = newNode;
} }
a->size += 1; a->size += 1;
} }
/*删除pos位置的Array_节点*/ /*删除pos位置的Array_节点*/
void Array_delete_pos(struct Array *a, int pos, void (*rel_)(void *)){ void Array_delete_pos(struct Array *a, int pos, void (*rel_)(void *)){
assert("Array_delete" && pos >= 0 && pos < a->size && a->size != 0); assert("Array_delete" && pos >= 0 && pos < a->size && a->size != 0);
struct Array_ *node = a->front, *freeNode; struct Array_ *node = a->front, *freeNode;
if(pos == 0){ if(pos == 0){
freeNode = a->front; freeNode = a->front;
a->front = a->front->next; a->front = a->front->next;
rel_(freeNode->p); rel_(freeNode->p);
free(freeNode); free(freeNode);
}else{ }else{
for(int i = 0; i < pos-1; i ++) node = node->next; for(int i = 0; i < pos-1; i ++) node = node->next;
freeNode = node->next; freeNode = node->next;
node->next = node->next->next; node->next = node->next->next;
rel_(freeNode->p); rel_(freeNode->p);
free(freeNode); free(freeNode);
} }
a->size--; a->size--;
} }
/*删除node所指向的Array节点*/ /*删除node所指向的Array节点*/
void Array_delete_p(struct Array *a, struct Array_ *node, void (*rel_)(void *)){ void Array_delete_p(struct Array *a, struct Array_ *node, void (*rel_)(void *)){
assert("Array_delete_p" && node != a->back); assert("Array_delete_p" && node != a->back);
struct Array_ *freeNode; struct Array_ *freeNode;
if(node == a->front){ if(node == a->front){
freeNode = a->front; freeNode = a->front;
a->front = a->front->next; a->front = a->front->next;
rel_(freeNode->p); rel_(freeNode->p);
free(freeNode); free(freeNode);
}else{ }else{
freeNode = node->next; freeNode = node->next;
node->next = node->next->next; node->next = node->next->next;
rel_(freeNode->p); rel_(freeNode->p);
free(freeNode); free(freeNode);
} }
a->size--; a->size--;
} }
/*交换内容即p指针*/ /*交换内容即p指针*/
void Array__swap(struct Array_ *a, struct Array_ *b){ void Array__swap(struct Array_ *a, struct Array_ *b){
void *t = b->p; void *t = b->p;
b->p = a->p; b->p = a->p;
a->p = t; a->p = t;
} }
/* /*
reverse(reverse == 0) reverse(reverse == 0)
func(a,b) func(a,b)
a>b:>0 a>b:>0
a==b:0 a==b:0
a < b:<0 a < b:<0
*/ */
void Array_sort(struct Array *a, int (*func)(void *, void *), int reverse){ void Array_sort(struct Array *a, int (*func)(void *, void *), int reverse){
reverse = reverse ? -1 : 1; reverse = reverse ? -1 : 1;
struct Array_ *sorted = a->back, *p; struct Array_ *sorted = a->back, *p;
while(a->front->next != sorted){ while(a->front->next != sorted){
for(p = a->front; p->next != sorted; p = p->next) for(p = a->front; p->next != sorted; p = p->next)
if(reverse*func(p->p,p->next->p) > 0) if(reverse*func(p->p,p->next->p) > 0)
Array__swap(p, p->next); Array__swap(p, p->next);
sorted = p; sorted = p;
} }
} }
/*指定类型 转换(void)Array.p中的内容*/ /*指定类型 转换(void)Array.p中的内容*/
#define PAT(TypeName, Array_Pointer) ((TypeName *)Array_Pointer->p) #define PAT(TypeName, Array_Pointer) ((TypeName *)Array_Pointer->p)
/*链表的遍历*/ /*链表的遍历*/
#define Range(arr) for(struct Array_ *p = arr.front; p != arr.back; p = p->next) #define Range(arr) for(struct Array_ *p = arr.front; p != arr.back; p = p->next)
/*链表指定类型的初始化*/ /*链表指定类型的初始化*/
#define DEF_ARRAY(Type, name) #define DEF_ARRAY(Type, name)
void DoNothing(){} void DoNothing(){}
/*记录每Array容器对象的信息*/ /*记录每Array容器对象的信息*/
struct ArrayObjects{ struct ArrayObjects{
void *p_obj; /*Array对象的地址*/ void *p_obj; /*Array对象的地址*/
}; };
/*为每一个Array容器类实现释放管理*/ /*为每一个Array容器类实现释放管理*/
struct ArrayClass{ struct ArrayClass{
char *TypeName; /*容器内置类型的名称*/ char *TypeName; /*容器内置类型的名称*/
void (*rel_)(void *);/*释放Array对象内部单个元素数据的方式*/ void (*rel_)(void *);/*释放Array对象内部单个元素数据的方式*/
struct Array objects;/*该内置类型所有Array对象的信息*/ struct Array objects;/*该内置类型所有Array对象的信息*/
}; };
/*存储所有Array容器类*/ /*存储所有Array容器类*/
struct Array ArrayList; struct Array ArrayList;
/*以TypeName注册一个新的ArrayClass并且指定Rel__Func为释放单个元素的方式*/ /*以TypeName注册一个新的ArrayClass并且指定Rel__Func为释放单个元素的方式*/
void ArrayClass_Reg(char *TypeName, void (*Rel__Func)(void *p)){ void ArrayClass_Reg(char *TypeName, void (*Rel__Func)(void *p)){
struct ArrayClass ac; struct ArrayClass ac;
ac.TypeName = malloc_s_strcpy(TypeName); ac.TypeName = malloc_s_strcpy(TypeName);
ac.rel_ = Rel__Func; ac.rel_ = Rel__Func;
Array_create(&ac.objects, sizeof(struct ArrayObjects)); Array_create(&ac.objects, sizeof(struct ArrayObjects));
Array_insert(&ArrayList, &ac, 0); Array_insert(&ArrayList, &ac, 0);
} }
/*向给定TypName的ArrayClass注册一个新的对象对象地址为p_obj*/ /*向给定TypName的ArrayClass注册一个新的对象对象地址为p_obj*/
void ArrayObj_Reg(char *TypeName, void *p_obj){ void ArrayObj_Reg(char *TypeName, void *p_obj){
struct Array_ *p; struct Array_ *p;
for(p = ArrayList.front; p != ArrayList.back; p = p->next) for(p = ArrayList.front; p != ArrayList.back; p = p->next)
if(strcmp(((struct ArrayClass*)p->p)->TypeName, TypeName) == 0) if(strcmp(((struct ArrayClass*)p->p)->TypeName, TypeName) == 0)
break; break;
Array_insert((&((struct ArrayClass*)p->p)->objects), &(struct ArrayObjects){p_obj}, 0); Array_insert((&((struct ArrayClass*)p->p)->objects), &(struct ArrayObjects){p_obj}, 0);
} }
/*释放ArrayList中单个元素占用的资源*/ /*释放ArrayList中单个元素占用的资源*/
void ArrayList_Rel_(void *p_class){ void ArrayList_Rel_(void *p_class){
free(((struct ArrayClass *)p_class)->TypeName); free(((struct ArrayClass *)p_class)->TypeName);
Array_release(&((struct ArrayClass *)p_class)->objects, DoNothing); Array_release(&((struct ArrayClass *)p_class)->objects, DoNothing);
} }
/*初始化Array_List*/ /*初始化Array_List*/
void ArrayList_Init(){ void ArrayList_Init(){
Array_create(&ArrayList, sizeof(struct ArrayClass)); Array_create(&ArrayList, sizeof(struct ArrayClass));
} }
/*释放ArrayList占用的资源*/ /*释放ArrayList占用的资源*/
void ArrayList_Rel(){ void ArrayList_Rel(){
Array_release(&ArrayList, ArrayList_Rel_); Array_release(&ArrayList, ArrayList_Rel_);
} }
/*主动提前释放资源,对于局部变量,需要在其被编译器释放前主动释放占用资源,防止内存泄漏*/ /*主动提前释放资源,对于局部变量,需要在其被编译器释放前主动释放占用资源,防止内存泄漏*/
void Array_Obj_PreRelease(struct Array *unrel_obj){ void Array_Obj_PreRelease(struct Array *unrel_obj){
for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next)
for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next)
if(unrel_obj == ((struct ArrayObjects*)q->p)->p_obj){ if(unrel_obj == ((struct ArrayObjects*)q->p)->p_obj){
printf("%s\n", ((struct ArrayClass *)p->p)->TypeName); Array_release(unrel_obj, ((struct ArrayClass *)p->p)->rel_);
Array_release(unrel_obj, ((struct ArrayClass *)p->p)->rel_); Array_delete_p(&((struct ArrayClass *)p->p)->objects, q, DoNothing);
Array_delete_p(&((struct ArrayClass *)p->p)->objects, q, DoNothing); return ;
return ; }
} assert("Array_Obj_PreRelease:NotFound");
assert("Array_Obj_PreRelease:NotFound"); }
} /*根据ArrayObj反查ArrayClass*/
/*根据ArrayObj反查ArrayClass*/ struct ArrayClass *ArrayList_Find_Class_From_Obj(struct Array *a){
struct ArrayClass *ArrayList_Find_Class_From_Obj(struct Array *a){ for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next)
for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next)
for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) if(a == ((struct ArrayObjects*)q->p)->p_obj)
if(a == ((struct ArrayObjects*)q->p)->p_obj) return (struct ArrayClass *)p->p;
return (struct ArrayClass *)p->p; assert("ArrayList_Find_Class_From_Obj:NotFound");
assert("ArrayList_Find_Class_From_Obj:NotFound"); }
} /*重写简化的Array_delete*/
/*重写简化的Array_delete*/ void Array_deletepos(struct Array *a, int pos){
void Array_deletepos(struct Array *a, int pos){ Array_delete_pos(a, pos, ArrayList_Find_Class_From_Obj(a)->rel_);
Array_delete_pos(a, pos, ArrayList_Find_Class_From_Obj(a)->rel_); }
} void Array_deletep(struct Array *a, struct Array_ *node){
void Array_deletep(struct Array *a, struct Array_ *node){ Array_delete_p(a, node, ArrayList_Find_Class_From_Obj(a)->rel_);
Array_delete_p(a, node, ArrayList_Find_Class_From_Obj(a)->rel_); }
} /*MARCO:为Type注册一个新的ArrayClass并且指定Rel__Func为释放单个元素的方式*/
/*MARCO:为Type注册一个新的ArrayClass并且指定Rel__Func为释放单个元素的方式*/ #define DECLARE_ARRAY(Type, RelFunc) ArrayClass_Reg(#Type, RelFunc);
#define DECLARE_ARRAY(Type, RelFunc) ArrayClass_Reg(#Type, RelFunc); /*
/* MARCO:TypeArrayClassArrName
MARCO:TypeArrayClassArrName Example:
Example: struct ARRAY(a, struct A);
struct ARRAY(a, struct A); ^^^^^^___________________^
^^^^^^___________________^ */
*/ #define ARRAY(ArrName, Type) \
#define ARRAY(ArrName, Type) \ Array ArrName; \
Array ArrName; \ Array_create(&ArrName, sizeof(Type)); \
Array_create(&ArrName, sizeof(Type)); \ ArrayObj_Reg(#Type, &ArrName)
ArrayObj_Reg(#Type, &ArrName)
#define ARRAY_BIND(ArrName, Type) \
#define ARRAY_BIND(ArrName, Type) \ Array_create(&ArrName, sizeof(Type)); \
Array_create(&ArrName, sizeof(Type)); \ ArrayObj_Reg(#Type, &ArrName);
ArrayObj_Reg(#Type, &ArrName);
/*
/* Example:
Example:
struct A{
struct A{ int a;
int a; };
}; void rel_(void*p){}
void rel_(void*p){} int main(){
int main(){ Array_Class_Init();
Array_Class_Init(); DECLARE_ARRAY(struct A, rel_)
DECLARE_ARRAY(struct A, rel_) struct ARRAY(a, struct A);
struct ARRAY(a, struct A);
Array_Obj_PreRelease(&a);
Array_Obj_PreRelease(&a); Array_Class_Rel();
Array_Class_Rel(); }
} */
*/ #endif
#endif
#define ARRAY_INCLUDED #define ARRAY_INCLUDED
Loading…
Cancel
Save