comparison DynArray.c @ 4:f35e64d7a42b

Working version used for probes in Master Env
author Me
date Sat, 30 Oct 2010 22:12:32 -0700
parents 8473c52c6f0e
children 2915fb26c9e2 601709e9f2a4
comparison
equal deleted inserted replaced
1:9040f3edda48 2:a8b72852155d
7 7
8 8
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <malloc.h> 10 #include <malloc.h>
11 11
12 #include "DynArray.h"
12 13
13 14
14 /*make a struct with the sizes and a pointer to the
15 * array, but hide a reverse pointer at the front of the array that
16 * points back to the vector struct -- that way, can pass around the
17 * array when doing work on elements, but when need to increase size,
18 * get pointer to vector struct and use that, which will change the
19 * ptr to the array in the vector struc, and return the new pointer..
20 * so from the point of changing size on, have the correct array ptr,
21 * and also all other places that initiate a sequence later will get
22 * the array ptr from the vector struct at the sequence start..
23 */
24 bool8
25 addToVect( Vector *vect, void *ptrToElem )
26 { int32 numPtrsInVect, sizeOfVect;
27 15
28 /* 16 DynArrayInfo *
29 numPtrsInVect = *(vect -1); //num ptrs is "hidden" in front 17 makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray )
30 sizeOfVect = *(vect -2); 18 { DynArrayInfo *info;
31 */
32 numPtrsInVect = vect->numPtrsInArray;
33 sizeOfVect = vect->sizeOfArray;
34 19
35 if( numPtrsInVect >= sizeOfVect ) return FALSE; 20 info = malloc( sizeof(DynArrayInfo) );
36 21
37 vect->arrayOfPtrs[numPtrsInVect] = ptrToElem; 22 info->addrOfPtrToArray = addrOfPtrToArray;
38 vect->numPtrsInArray++; 23 info->sizeOfArray = sizeOfArray;
24 info->numInArray = 0;
39 } 25 }
40 26
41 void ** 27 DynArrayInfo *
42 increaseSizeOfVect( Vector *vect ) 28 makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray )
43 { int32 oldSizeOfArray, newSizeOfArray, i; 29 { DynArrayInfo *info;
30
31 info = malloc( sizeof(DynArrayInfo) );
32
33 info->addrOfPtrToArray = addrOfPtrToArray;
34
35 *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) );
36 info->sizeOfArray = sizeOfArray;
37 info->numInArray = 0;
38 }
39
40
41 /*A dynamic array is same as any other array, but add a DynArrayInfo next
42 * to it. Accesses and updates of array indexes are done normally, it's
43 * only when add a new element into array that use the extra info.
44 * An add can cause the pointer to the normal array to change.. so must
45 * be protected to single VP at a time.
46 *
47 *Only need to use this Fn when need a new index, higher than any previous
48 */
49 int32
50 addToDynArray( void *value, DynArrayInfo *info )
51 { int32 numInArray, sizeOfArray;
52 void **array;
53
54 numInArray = info->numInArray;
55 sizeOfArray = info->sizeOfArray;
56
57 if( numInArray >= sizeOfArray )
58 {
59 increaseSizeOfDynArrayTo( info, sizeOfArray * 2 );
60 }
61
62 array = *(info->addrOfPtrToArray);
63 array[ numInArray ] = value;
64 info->numInArray++;
65
66 return numInArray; //pre-incr value is the index put value into
67 }
68
69
70 /*Use this when know how many things going to add in -- then can do this
71 * once and use as normal array afterwards. If later add another chunk,
72 * do this again. Note, this makes new size be just big enough to hold
73 * highest index, so will do a linear number of copies if use only this.
74 *To cut down on number of copies, can use the increaseSizeTo Fn to
75 * exponentially increase size..
76 */
77 void
78 makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex )
79 {
80 if( info->sizeOfArray <= highestIndex )
81 {
82 increaseSizeOfDynArrayTo( info, highestIndex + 1 );
83 }
84 info->numInArray = highestIndex + 1;
85 }
86
87
88 /*Only use this if certain new size is bigger than current size
89 */
90 void
91 increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize )
92 { int32 oldSizeOfArray, i;
44 void **newArray, **oldArray; 93 void **newArray, **oldArray;
45 94
46 oldSizeOfArray = vect->sizeOfArray; 95 oldSizeOfArray = info->sizeOfArray;
47 newSizeOfArray = oldSizeOfArray * 2; 96 if( newSize <= oldSizeOfArray ) return;
48 oldArray = vect->arrayOfPtrs; 97
49 newArray = malloc( (newSizeOfArray + 1) * sizeof(void *) ); 98 oldArray = *(info->addrOfPtrToArray);
50 *newArray = vect; 99 newArray = malloc( newSize * sizeof(void *) );
51 newArray++; 100
52 for( i = 0; i < oldSizeOfArray; i++ ) 101 for( i = 0; i < oldSizeOfArray; i++ )
53 { 102 {
54 newArray[i] = oldArray[i]; 103 newArray[i] = oldArray[i];
55 } 104 }
56 vect->arrayOfPtrs = newArray; 105 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr
57 vect->sizeOfArray = newSizeOfArray; 106 info->sizeOfArray = newSize;
58 107
59 free( oldArray -1 ); 108 free( oldArray );
60 return newArray;
61 } 109 }
62 110
63 /* 111
64 bool8 112 /* Frees the array, plus the info
65 forAllInVectDo( ptrToFnTakesVectElemAsVoid* ) 113 */
114 void
115 freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr )
66 { 116 {
67 return success; 117 forAllInDynArrayDo( info, freeFnPtr );
118 free( *(info->addrOfPtrToArray) );
119 free( info );
68 } 120 }
69 */ 121
122 /* Only frees the info
123 */
124 void
125 freeDynArrayFlat( DynArrayInfo *info )
126 {
127 free( info );
128 }
129
130
131 /*The function has a fixed prototype: takes a void * returns void
132 * So, the function has to internally cast void * to whatever data struc..
133 */
134 void
135 forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr )
136 { int32 idx;
137 void **array;
138
139 array = *(info->addrOfPtrToArray);
140 for( idx = 0; idx < info->numInArray; idx++ )
141 {
142 (*fnPtr)(array[idx]);
143 }
144 }
145