Dynamic pointer array using C language Dynamic arrays
The C language implements dynamic arrays.
Basic principle: Prepare an array with a fixed length in advance. If the length is not enough, realloc is a region. In addition, the length of the array needs to be reduced when array elements are reduced.
Main interfaces:
Cp_bool DyArrayAppend (DyArray * pArr, void * pData) // Add data to the end of the array cp_bool partition (DyArray * pArr, cp_int32 nNeed) // extend the array cp_bool DyArrayDelete (DyArray * pArr, cp_int32 nIndex) // Delete the element by indexcp_bool DyArrayShrink (DyArray * pArr) // scale down the Array
Source code: (c Implementation of iOS platform)
//// DyArray. h // dataStruct // Created by hherima on 14-7-28. // Copyright (c) 2014. all rights reserved. // # ifndef dataStruct_dyArray_h # define dataStruct_dyArray_h # include
Enum {CP_FALSE = 0, CP_TRUE =! CP_FALSE}; typedef unsigned char cp_bool; typedef signed int cp_int32; typedef void (* DataDestroyFunc) (void *); typedef cp_bool (* DataCmpFunc) (void *, void *); typedef void (* DataVisitFunc) (void *); # define F_MALLOC_TYPE (s) (s *) f_malloc (sizeof (s )) # define FREEFUN free # define MIN_PRE_ALLOCATE_SIZE 10 // The initial size of the dynamic array. # define MEMSETFUN memset # define REALLOCFUN realloc # define MALLOCFUN malloc struct DynamicArray {void ** m_ppData; // the address of the allocated array. cp_int32 m_nAllocSize; // the allocated array size. cp_int32 m_nSize; // the used size of the array. dataDestroyFunc m_fDestroy; // the callback function to destroy one data. dataCmpFunc m_fCmp; // the callback function to compare one data. dataVisitFunc m_fVisit; // the callback function to visit each data .}; typedef struct DynamicArray DyArray; DyArray * DyArrayCreate (partition); cp_bool DyArrayInsert (DyArray * pArr, cp_int32 nIndex, void * pData); cp_bool partition (DyArray * pArr, void * pData ); cp_bool aggregate (DyArray * pArr, void * pData); cp_bool DyArrayDelete (DyArray * pArr, cp_int32 nIndex); cp_bool aggregate (DyArray * pArr, cp_int32 nBegin, cp_int32 nEnd ); cp_bool aggregate (DyArray * pArr, cp_int32 nIndex, void ** ppData); cp_bool DyArrayGetFirst (DyArray * pArr, void ** ppData); cp_bool DyArrayGetLast (DyArray * pArr, void ** ppData); cp_bool partition (DyArray * pArr, cp_int32 nIndex, void * pData); cp_int32 DyArrayLength (DyArray * pArr); cp_int32 DyArrayFind (DyArray * pArr, DataCmpFunc pCmp, void * pData); cp_bool DyArrayForEach (DyArray * pArr, required pVisit); void DyArrayDestroy (DyArray * pArr); void Merge (DyArray * pArr, DataDestroyFunc pDataDestroy ); void DyArrayReset (DyArray * pArr); // shrink void DyArrayClear (DyArray * pArr); // not shrink void DyArrayResetCustom (DyArray * pArr, DataDestroyFunc pDataDestroy ); void DyArrayClearCustom (DyArray * pArr, DataDestroyFunc pDataDestroy); // not shrink # endif
//// DyArray. c // dataStruct // Created by hherima on 14-7-28. // Copyright (c) 2014. all rights reserved. // # include "dyArray. h "void * f_malloc (cp_int32 size) {void * p = MALLOCFUN (size); if (p) MEMSETFUN (p, 0, size); return p ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayCreate [description]: create a dynamic pointer array with the length of MIN_PRE_ALLOCATE_SIZE. [parameter]: pDataDestroy: The callback function to destroy one data in data array. [return value ]: the address of the dynamic pointer array *********************************** **************************************** * **********************/DyArray * DyArrayCreate (DataDestroyFunc pDataDestroy) {DyArray * pArr = NULL; pArr = F_MALLOC_TYPE (DyArray); // if the input parameter is invalid, return. if (! PArr) {return NULL;} // malloc memory for dynamic array and iniatilize it. pArr-> m_fDestroy = pDataDestroy; pArr-> m_ppData = (void *) f_malloc (sizeof (void *) * MIN_PRE_ALLOCATE_SIZE); if (! PArr-> m_ppData) {free (pArr); return NULL;} pArr-> m_nAllocSize = MIN_PRE_ALLOCATE_SIZE; return pArr ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayGetByIndex [description]: Obtain the array element by index [parameter]: pArr: the array's address. nIndex: the element's position. ppData: out parameter, to record the element's pointer. [return value]: true or false. ********************* **************************************** * ***********************************/Cp_bool dyArrayGetByIndex (DyArray * pArr, cp_int32 nIndex, void ** ppData) {// if the input parameter is invalid, return. if (! PArr | nIndex <0 |! PpData | nIndex> = pArr-> m_nSize) {* ppData = NULL; return CP_FALSE;} * ppData = pArr-> m_ppData [nIndex]; // get the related element. return CP_TRUE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayGetFirst [description]: gets the first element of the array. [parameter]: pArr: the array's address. ppData: out parameter, to record the element's pointer. [return value]: true or false. *********** **************************************** **************************************** * ******/Cp_bool DyArrayGetFirst (DyArray * pArr, void ** ppData) {return DyArrayGetByIndex (pArr, 0, ppData )? CP_TRUE: CP_FALSE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayGetLast [description]: Get the last element of the array [parameter]: pArr: the array's address. ppData: out parameter, to record the element's pointer. [return value]: true or false. **************************************** **************************************** * *****************/cp_bool DyArrayGetLast (DyArray * pA Rr, void ** ppData) {return DyArrayGetByIndex (pArr, pArr-> m_nSize-1, ppData )? CP_TRUE: CP_FALSE ;} /*************************************** **************************************** * ******************* [function name ]: dyArraySetByIndex [description]: sets the array element by index [parameter]: pArr: the array's address. nIndex: the element's position. pData: the element's pointer. [return value]: true or false. **************************************** **************************************** * *****************/cp_bool DyArraySetByIn Dex (DyArray * pArr, cp_int32 nIndex, void * pData) {// if the input parameter is invalid, return. if (! PArr | nIndex <0) {return CP_FALSE;} pArr-> m_ppData [nIndex] = pData; // find the related position and set its value. return CP_TRUE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayLength [description]: Get the length of the array [parameter]: pArr: the array's address. [return value]: array length. **************************************** **************************************** ************ * *****/Cp_int32 DyArrayLength (DyArray * pArr) {return pArr? PArr-> m_nSize:-1 ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayFind [description]: Find the specified Element in the array [parameter]: pArr: the array's address. pCmp: the callback function to compare the data. pData: the search destination in the array. [return value]: If the returned position is successful, otherwise, the system returns-1 ************************************ **************************************** ***********************/ Cp_int32 DyArrayFind (DyArray * pArr, DataCmpFunc pCmp, void * pData) {cp_int32 I; // if the input parameter is invalid, return. if (! PArr) {return-1;} // visit each one to find the right one. for (I = 0; I
M_nSize; I ++) {if (pCmp (pArr-> m_ppData [I], pData) = CP_TRUE) {return I ;}} else {// if NO compare funciton, just compare the address. if (pArr-> m_ppData [I] = pData) {return I ;}} return-1 ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayForEach [description]: traverse the array [parameter]: pArr: the array's address. pVisit: the callback function to vis It the data. [return value]: returns true if the request is successful, otherwise, false ************************************** **************************************** * ******************/cp_bool DyArrayForEach (DyArray * pArr, dataVisitFunc pVisit) {cp_int32 I; // if the input parameter is invalid, return. if (! PArr |! PVisit) {return CP_FALSE;} // visit each one with the visit function. for (I = 0; I
M_nSize; I ++) {pVisit (pArr-> m_ppData [I]);} return CP_TRUE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayDestroy [description]: destroys the entire array [parameter]: pArr: the array's address. [return value ]: NA *************************************** **************************************** * ******************/void DyArrayDestroy (DyArray * pArr) {cp_int32 I; // if the input parameter I S invalid, return. if (! PArr) {return;} // Using destroy function to destroy each element's memory. if (pArr-> m_fDestroy) {for (I = 0; I
M_nSize; I ++) {pArr-> m_fDestroy (pArr-> m_ppData [I]) ;}// free the array. FREEFUN (pArr-> m_ppData); pArr-> m_ppData = NULL; FREEFUN (pArr); pArr = NULL ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayDestroyCustom [description]: Use the User Function, small circle array [parameter]: pArr: the array's address. pDataDestroy: user's destroy function. [return value]: NA *********************************** **************************************** * *********************/Void DyArrayDestroyCustom (DyArray * pArr, dataDestroyFunc pDataDestroy) {cp_int32 I; // if the input parameter is invalid, return. if (! PArr) {return;} // Using destroy function to destroy each element's memory. if (pDataDestroy) {for (I = 0; I
M_nSize; I ++) {pDataDestroy (pArr-> m_ppData [I]) ;}// free the array. FREEFUN (pArr-> m_ppData); pArr-> m_ppData = NULL; FREEFUN (pArr );} /*************************************** **************************************** * ******************* [function name ]: dyArrayExpand [description]: extended array [parameter]: pArr: the array's address. nNeed: the needed new size. [return value ]: if true is returned successfully, false is returned ********************************* **************************** * ***********************************/Cp_bool dyArrayExpand (DyArray * pArr, cp_int32 nNeed) {cp_int32 allocSize = 0; void ** data = NULL; // if the input parameter is invalid, return. if (! PArr) {return CP_FALSE ;}// if need, expand to 1.5 times of the original size. if (pArr-> m_nSize + nNeed)> pArr-> m_nAllocSize) {allocSize = pArr-> m_nAllocSize + (pArr-> m_nAllocSize> 1 ); data = (void **) REALLOCFUN (pArr-> m_ppData, sizeof (void *) * allocSize); if (data! = NULL) {// clear the expanded space of the new memory. MEMSETFUN (data + pArr-> m_nAllocSize, 0, (allocSize-pArr-> m_nAllocSize) * sizeof (void *); pArr-> m_ppData = data; pArr-> m_nAllocSize = allocSize;} return (pArr-> m_nSize + nNeed) <= pArr-> m_nAllocSize )? CP_TRUE: CP_FALSE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayInsert [description]: insert array by index [parameter]: pArr: the array's address. nIndex: the position in the array to insert new data. pData: the data to be inserted. [return value ]: if it succeeds, return true. Otherwise, false ********************************** **************************************** * ************************/c P_bool DyArrayInsert (DyArray * pArr, cp_int32 nIndex, void * pData) {cp_bool bRet = CP_FALSE; cp_int32 nCursor = nIndex; cp_int32 I; // if the input parameter is invalid, return. if (! PArr) {return CP_FALSE;} // get the right cursor. nCursor = nCursor <pArr-> m_nSize? NCursor: pArr-> m_nSize; if (DyArrayExpand (pArr, 1) = CP_TRUE) {// move all the elements after the cursor to the next positon. for (I = pArr-> m_nSize; I> nCursor; I --) {pArr-> m_ppData [I] = pArr-> m_ppData [I-1];} // set the cursor's value. pArr-> m_ppData [nCursor] = pData; pArr-> m_nSize ++; bRet = CP_TRUE;} return bRet ;} /*************************************** **************************************** * * **************** [Function name]: DyArrayPrepend [description]: Add a data entry in the array. [parameter]: pArr: the array's address. pData: the data to be added. [return value]: If true is returned successfully, otherwise, false ************************************** **************************************** * ******************/cp_bool DyArrayPrepend (DyArray * pArr, void * pData) {return DyArrayInsert (pArr, 0, pData )? CP_TRUE: CP_FALSE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayAppend [description]: add data to the end of the array [parameter]: pArr: the array's address. pData: the data to be added. [return value]: returns true if the request is successful, otherwise, false ************************************** **************************************** * ******************/cp_bool DyArrayAppend (DyArray * pArr, void * pData) {return DyAr RayInsert (pArr, pArr-> m_nSize, pData )? CP_TRUE: CP_FALSE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayShrink [description]: scale down an array [parameter]: pArr: the array's address. [return value ]: true or false ************************************* **************************************** * ********************/cp_bool DyArrayShrink (DyArray * pArr) {cp_int32 nAllocSize = 0; void ** pData = NULL; // if the input [parameter] Is invalid, return. if (! PArr) {return CP_FALSE;} // if need, shrink the array to 1.5 times of elements number. if (pArr-> m_nSize <(pArr-> m_nAllocSize> 1) & (pArr-> m_nAllocSize> MIN_PRE_ALLOCATE_SIZE )) {nAllocSize = pArr-> m_nSize + (pArr-> m_nSize> 1); pData = (void **) REALLOCFUN (pArr-> m_ppData, sizeof (void *) * nAllocSize); if (pData! = NULL) {// clear memory of the unused space of new memory. MEMSETFUN (pData + pArr-> m_nSize, 0, (nAllocSize-pArr-> m_nSize) * sizeof (void *); pArr-> m_ppData = pData; pArr-> m_nAllocSize = nAllocSize;} return CP_TRUE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayDelete [description]: Delete the element by index [parameter]: pArr: the array's address. nIndex: the positio N in the array to delete useless data. [return value ]: true or false ************************************* **************************************** * *******************/cp_bool DyArrayDelete (DyArray * pArr, cp_int32 nIndex) {cp_int32 I; // if the input parameter is invalid, return. if (! PArr) {return CP_FALSE;} // destroy the element with destroy function. if (pArr-> m_fDestroy) {pArr-> m_fDestroy (pArr-> m_ppData [nIndex]);} // move the elements after 'nindex' to the previous one. for (I = nIndex; (I + 1) <pArr-> m_nSize; I ++) {pArr-> m_ppData [I] = pArr-> m_ppData [I + 1];} // set the last one to null. pArr-> m_ppData [I] = NULL; pArr-> m_nSize --; // if need, shrink the size. dyArrayShrink (pArr); re Turn CP_TRUE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayDeleteEx [description]: Delete the element by index (Extension) [parameter]: pArr: the array's address. nIndex: the position in the array to delete useless data. nEdn: [return value ]: true or false ************************************* **************************************** * ********************/cp_bool DyArrayDeleteEx (DyArray * pArr, cp_int32 nBegin, cp_int32 nEnd) {cp_int32 I, nLen = 0; // if the input parameter is invalid, return. // if (! PArr & nBegin> nEnd & nBegin <0 & nBegin> = pArr-> m_nSize & nEnd <0 & nEnd> = pArr-> m_nSize) if (! PArr) {return CP_FALSE;} // destroy the element with destroy function. if (pArr-> m_fDestroy) {for (I = nBegin; I <= nEnd; I ++) {pArr-> m_fDestroy (pArr-> m_ppData [I]);} // move the elements after 'nindex' to the previous one. nLen = nEnd-nBegin + 1; for (I = nBegin; (I + nLen) <pArr-> m_nSize; I ++) {pArr-> m_ppData [I] = pArr-> m_ppData [I + nLen];} // set the last one to null. // pArr-> m_ppData [I] = NULL; pArr-> m_nSize-= nLen; // If need, shrink the size. dyArrayShrink (pArr); return CP_TRUE ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayReset [description]: clears array data and reduces the size of the array to the original size. [parameter]: pArr: the array's address. [return value]: none. **************************************** **************************************** * *****************/void DyArrayReset (DyArray * pArr) {cp_int32 I; void ** pD Ata = NULL; // if the input parameter is invalid, return. if (! PArr) {return;} // reset all the elements with destroy function. if (pArr-> m_fDestroy) {for (I = 0; I
M_nSize; I ++) {pArr-> m_fDestroy (pArr-> m_ppData [I]) ;}} pArr-> m_nSize = 0; // if need, shrink the size. if (pArr-> m_nAllocSize> MIN_PRE_ALLOCATE_SIZE) {pData = (void **) REALLOCFUN (pArr-> m_ppData, sizeof (void *) * MIN_PRE_ALLOCATE_SIZE); if (pData! = NULL) {pArr-> m_ppData = pData; pArr-> m_nAllocSize = MIN_PRE_ALLOCATE_SIZE;} if (pArr-> m_ppData) {MEMSETFUN (pArr-> m_ppData, 0, sizeof (void *) * pArr-> m_nAllocSize );}}} /*************************************** **************************************** * ******************* [function name ]: dyArrayClear [description]: clears the array data without reducing the array size to the original size. [parameter]: pArr: the array's address. [return value ]: NA *************************************** ******************* **************************************** */Void DyArrayClear (DyArray * pArr) {cp_int32 I; void ** pData = NULL; // if the input parameter is invalid, return. if (! PArr) {return;} // reset all the elements with destroy function. if (pArr-> m_fDestroy) {for (I = 0; I
M_nSize; I ++) {pArr-> m_fDestroy (pArr-> m_ppData [I]) ;}} pArr-> m_nSize = 0 ;} /*************************************** **************************************** * ******************* [function name ]: dyArrayResetCustom [description]: clears the array and uses the User Function to reduce the array to the original size. [parameter]: pArr: the array's address. pDataDestroy: user's destroy function. [return value ]: NA *************************************** **************************************** * *******************/vo Id DyArrayResetCustom (DyArray * pArr, DataDestroyFunc pDataDestroy) {cp_int32 I; void ** pData = NULL; // if the input parameter is invalid, return. if (! PArr) {return;} // reset all the elements with destroy function. if (pDataDestroy) {for (I = 0; I
M_nSize; I ++) {pDataDestroy (pArr-> m_ppData [I]) ;}} pArr-> m_nSize = 0; // if need, shrink the size. if (pArr-> m_nAllocSize> MIN_PRE_ALLOCATE_SIZE) {pData = (void **) REALLOCFUN (pArr-> m_ppData, sizeof (void *) * MIN_PRE_ALLOCATE_SIZE); if (pData! = NULL) {pArr-> m_ppData = pData; pArr-> m_nAllocSize = MIN_PRE_ALLOCATE_SIZE;} if (pArr-> m_ppData) {MEMSETFUN (pArr-> m_ppData, 0, sizeof (void *) * pArr-> m_nAllocSize );}}} /*************************************** **************************************** * ******************* [function name ]: dyArrayClearCustom [description]: clears the array and uses the user function without reducing the array to the original size. [parameter]: pArr: the array's address. pDataDestroy: user's destroy function. [return value]: NA ********* **************************************** **************************************** * ********/Void DyArrayClearCustom (DyArray * pArr, dataDestroyFunc pDataDestroy) {cp_int32 I; void ** pData = NULL; // if the input parameter is invalid, return. if (! PArr) {return;} // reset all the elements with destroy function. if (pDataDestroy) {for (I = 0; I
M_nSize; I ++) {pDataDestroy (pArr-> m_ppData [I]) ;}} pArr-> m_nSize = 0 ;}