A good C equivalent of STL vector?
here a simple vector-replacement, its ONE function for all, its strictly C89 and threadsafe;libs are too difficult for me, i use my own;no performance, but easy to use
/* owner-structs too */typedef struct { char name[20],city[20]; int salary;} My,*Myp;typedef char Str80[80];/* add here your type with its size */typedef enum {SPTR,INT=sizeof(int),DOUBLE=sizeof(double),S80=sizeof(Str80),MY=sizeof(My)} TSizes;typedef enum {ADD,LOOP,COUNT,FREE,GETAT,GET,REMOVEAT,REMOVE} Ops;void *dynarray(char ***root,TSizes ts,Ops op,void *in,void *out){ size_t d=0,s=in?ts?ts:strlen((char*)in)+1:0; char **r=*root; while( r && *r++ ) ++d; switch(op) { case ADD: if( !*root ) *root=calloc(1,sizeof r); *root=realloc(*root,(d+2)*sizeof r); memmove((*root)+1,*root,(d+1)*sizeof r); memcpy(**root=malloc(s),in,s); break; case LOOP: while( d-- ) ((void (*)(char*))in)((*root)[d]); break; case COUNT: return *(int*)out=d,out; case FREE: if(r) { ++d; while( d-- ) realloc((*root)[d],0); free(*root);*root=0; } break; case GETAT: { size_t i=*(size_t*)in; if(r && i<=--d) return (*root)[d-i]; } break; case GET: { int i=-1; while( ++i,d-- ) if( !(ts?memcmp:strncmp)(in,(*root)[d],s) ) return *(int*)out=i,out; return *(int*)out=-1,out; } case REMOVEAT: { size_t i=*(size_t*)in; if(r && i<=--d) { free((*root)[d-i]); memmove(&(*root)[d-i],&(*root)[d-i+1],(d-i+1)*sizeof r); return in; } } break; case REMOVE: while( *(int*)dynarray(root,ts,GET,in,&d)>=0 ) dynarray(root,ts,REMOVEAT,&d,0); } return 0;}void outmy(Myp s){ printf("\n%s,%s,%d",s->name,s->city,s->salary);}main(){ My z[]={{"Buffet","Omaha",INT_MAX},{"Jobs","Palo Alto",1},{"Madoff","NYC",INT_MIN}}; Str80 y[]={ "123","456","7890" }; char **ptr=0; int x=1; /* precondition for first use: ptr==NULL */ dynarray(&ptr,SPTR,ADD,"test1.txt",0); dynarray(&ptr,SPTR,ADD,"test2.txt",0); dynarray(&ptr,SPTR,ADD,"t3.txt",0); dynarray(&ptr,SPTR,REMOVEAT,&x,0); /* remove at index/key ==1 */ dynarray(&ptr,SPTR,REMOVE,"test1.txt",0); dynarray(&ptr,SPTR,GET,"t3.txt",&x); dynarray(&ptr,SPTR,LOOP,puts,0); /* another option for enumerating */ dynarray(&ptr,SPTR,COUNT,0,&x); while( x-- ) puts(ptr[x]); dynarray(&ptr,SPTR,FREE,0,0); /* frees all mallocs and set ptr to NULL */ /* start for another (user)type */ dynarray(&ptr,S80,ADD,y[0],0); dynarray(&ptr,S80,ADD,y[1],0); dynarray(&ptr,S80,ADD,y[2],0); dynarray(&ptr,S80,ADD,y[0],0); dynarray(&ptr,S80,LOOP,puts,0); dynarray(&ptr,S80,FREE,0,0); /* frees all mallocs and set ptr to NULL */ /* start for another (user)struct-type */ dynarray(&ptr,MY,ADD,&z[0],0); dynarray(&ptr,MY,ADD,&z[1],0); dynarray(&ptr,MY,ADD,&z[2],0); dynarray(&ptr,MY,ADD,&z[0],0); dynarray(&ptr,MY,LOOP,outmy,0); dynarray(&ptr,MY,FREE,0,0); return 0;}
There is sglib, which implements various lists,hashmaps and rbtrees in a generic fashion (i.e. by specializing over a type). There is also a fast sorting function for arrays: