Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > DynArray
changeset 32:958dcb7754ca rename_VMS_to_PR
PR branch -- added comments about safe usage
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Fri, 08 Mar 2013 05:37:45 -0800 |
| parents | 69980bfe2cf6 |
| children | 3ed337b6a04f c6e1805505c9 |
| files | DynArray.c DynArray.h |
| diffstat | 2 files changed, 46 insertions(+), 17 deletions(-) [+] |
line diff
1.1 --- a/DynArray.c Mon Sep 03 15:09:32 2012 -0700 1.2 +++ b/DynArray.c Fri Mar 08 05:37:45 2013 -0800 1.3 @@ -7,6 +7,7 @@ 1.4 1.5 1.6 #include <stdio.h> 1.7 +#include <malloc.h> 1.8 1.9 #include "DynArray.h" 1.10 1.11 @@ -45,7 +46,7 @@ 1.12 makePrivDynArrayOfSize_Ext( void ***addrOfPtrToArray, int32 sizeOfArray ) 1.13 { PrivDynArrayInfo *info; 1.14 1.15 - info = malloc( sizeof(PrivDynArrayInfo) ); 1.16 + info = (PrivDynArrayInfo*) malloc( sizeof(PrivDynArrayInfo) ); 1.17 1.18 info->addrOfPtrToArray = addrOfPtrToArray; 1.19 1.20 @@ -132,16 +133,16 @@ 1.21 */ 1.22 void 1.23 increaseSizeOfDynArrayTo( PrivDynArrayInfo *info, int32 newSize ) 1.24 - { int32 oldSizeOfArray, i; 1.25 + { int32 oldsizeOfArray, i; 1.26 void **newArray, **oldArray; 1.27 1.28 - oldSizeOfArray = info->sizeOfArray; 1.29 - if( newSize <= oldSizeOfArray ) return; 1.30 + oldsizeOfArray = info->sizeOfArray; 1.31 + if( newSize <= oldsizeOfArray ) return; 1.32 1.33 oldArray = *(info->addrOfPtrToArray); 1.34 newArray = PR_int__malloc( newSize * sizeof(void *) ); 1.35 1.36 - for( i = 0; i < oldSizeOfArray; i++ ) 1.37 + for( i = 0; i < oldsizeOfArray; i++ ) 1.38 { 1.39 newArray[i] = oldArray[i]; 1.40 } 1.41 @@ -157,16 +158,16 @@ 1.42 */ 1.43 void 1.44 increaseSizeOfDynArrayTo_Ext( PrivDynArrayInfo *info, int32 newSize ) 1.45 - { int32 oldSizeOfArray, i; 1.46 + { int32 oldsizeOfArray, i; 1.47 void **newArray, **oldArray; 1.48 1.49 - oldSizeOfArray = info->sizeOfArray; 1.50 - if( newSize <= oldSizeOfArray ) return; 1.51 + oldsizeOfArray = info->sizeOfArray; 1.52 + if( newSize <= oldsizeOfArray ) return; 1.53 1.54 oldArray = *(info->addrOfPtrToArray); 1.55 newArray = malloc( newSize * sizeof(void *) ); 1.56 1.57 - for( i = 0; i < oldSizeOfArray; i++ ) 1.58 + for( i = 0; i < oldsizeOfArray; i++ ) 1.59 { 1.60 newArray[i] = oldArray[i]; 1.61 }
2.1 --- a/DynArray.h Mon Sep 03 15:09:32 2012 -0700 2.2 +++ b/DynArray.h Fri Mar 08 05:37:45 2013 -0800 2.3 @@ -12,16 +12,44 @@ 2.4 #include "PR_impl/Services_Offered_by_PR/Memory_Handling/vmalloc.h" 2.5 2.6 2.7 - //A dynamic array is same as any other array, but add a DynArrayInfo next 2.8 - // to it. Accesses and updates of array indexes are done normally, it's 2.9 - // only when add a new element into array that use the extra info. 2.10 - // An add can cause the pointer to the normal array to change.. so must 2.11 - // be protected to single VP at a time. 2.12 + 2.13 +/*WARNING: Passing a DynArray as a param is dangerous if add to the DynArray 2.14 + * inside the function called! After adding or other operation that might 2.15 + * change the size, must re-read the addr of the chunk of memory that is the 2.16 + * array, via the DynArrayInfo. 2.17 + *Here's why: An array variable is a location, either on the stack 2.18 + * or in a field of a struct, whose contents is an addr. That addr is of the 2.19 + * first location of a chunk of locations. The DynArray works by changing 2.20 + * the chunk of locations, then modifying the contents of the original 2.21 + * array variable. It overwrites the addr of the old chunk of locations 2.22 + * with the addr of the new chunk. 2.23 + *But when the array variable is passed as a parameter, such as 2.24 + * in this: "foo( myDynArray )", then there are now two locations that hold 2.25 + * the addr of the same chunk of locations. So when a call is made that 2.26 + * adds to the DynArray, and inside the DynArray expands, it only updates 2.27 + * the original location with the new addr. Hence, the function will begin 2.28 + * overwriting memory past the end of the old chunk, because it still has 2.29 + * the pointer to the old chunk of locations. 2.30 + * 2.31 + *A dynamic array is accessed same as any other array. However, must use 2.32 + * dyn array calls, defined in here, in order to add or increase the size. 2.33 + * Must re-read the original array variable after any size-changing calls. 2.34 + *To pass a DynArray as a parameter to a function, can only pass the 2.35 + * DynArrayInfo, then inside the function, to read the addr of the first 2.36 + * location in the chunk of locations that is the array, do this: 2.37 + * "localArrayCopy = *(myDynArrayInfo->addrOfPtrToArray). After that, can 2.38 + * treat localArrayCopy as a normal array, as long as don't make any calls 2.39 + * that add or otherwise could increase the size of the array. If do make 2.40 + * such a call, then re-copy the array via the above. Can then use the 2.41 + * copy up until another add to the array. 2.42 + * 2.43 + */ 2.44 typedef struct 2.45 { 2.46 - void ***addrOfPtrToArray; //addr of array of ptrs == triple * 2.47 - int32 numInArray; 2.48 - int32 sizeOfArray; 2.49 + void ***addrOfPtrToArray; //addr of var that is array of ptrs == triple * 2.50 + int32 numInArray; //num entries added 2.51 + int32 sizeOfArray; //num elems alloc'd 2.52 + int32 sizeOfElem; //num bytes in one elem of array -- used in 2nd version 2.53 } 2.54 PrivDynArrayInfo; 2.55
