Embedded Systems December 2000 Vol13_13

Issue link:

Contents of this Issue


Page 154 of 197

What are the most desirable dynamiC memory allocation characteris- tics and what is the most flexible API with which to implement them? Third, and most important, I want the a llocatio n of th e multidimension- al struclure to be specified as a nest- ed po inte r to pointe r to ... array, as opposed to a sta tic alTay which is a pointe r to a block of memo ry upon which subscript calcula tio ns locate lh e individual ar ray eleme nts. All ANSI C compile rs u nderstand lhe diffe re nce. The reaso n fo r th is requireme nt is lO allow the a rray to be passed seque ntially to any deplh of subro utine, be mod ifi ed th ere, and be seen in modified form in any of the call el-s. This is not possible with sta tic mul tid imensional a rrays. Circumve n-tio n of thi s limita tio n results in th e decla ration of a 10l of globa l data. These types of arrays have been traditio nally impleme nted with multiple maLLocOs. A maLLocO is do ne to allocate storage for o ne or mo re leve ls of linked pointe r arrays, and fin ally maLLocOs are done for the da ta rows at the end of the poinle r links. For both embedded and no n- embedded environme nts, th is situa- tio n prese nts several diffi cul ties. Repeated calls to maLLocO wi ll allo- cate at non-local heap space locations. For a workstatio n environment this can result in multiple page faults dur- ing array access. In an embedded envi- ronme nt paging will not be a problem, but fragme ntatio n of heap space memory might be. This also results in a structure that is inherently difficull to free. The poin ter structure must e i th er be traversed and the rna L LocOed blocks freed recursively, or a list of maLLocOed block pointers must be saved for freeing, which is awkward. Lastly, we' re faced with the problem of cleaning up after a failed maLLocO. The SU-ucture will be o nly partially allocated, which makes free- ing more awkward sti ll. For all these reasons I want to allocate the entire SU-ucture witll only one maLLocO. This provides locali ty of reference, makes fl-eeing simple, does not fragment tile heap, and avoids multiple rna L LocO calls. Usage The resul t of all this is the implemen- tation defin ed by daa.c (dynamic array allocator). I have fo und these routi nes to be incred ibly usefu l over the years. Two implementations exist: tJ1e fi rst, daaO (and its associated dasO) is fo r embedded sys tems; the second, daav(), is for a wo rkstation environ- ment (I use Suns mo tly), where the page-aligned library allocation routine vaLLocO is availabl e. Let's examine a simple example of each from the test suite in daa.c. The first example, Test 1, uses daav() to allocate a four-d ime nsional double army with no n-zero subscript- ing and without ini tialization. The second example-Test 2, using daaO-allocates the same array with ini tialization: int err_code = 0; char *free-ptr; char *base-ptr; int d[4J = {3, 5, 4, 2}; int st[4] = {-1, -5, 10, O}; doubLe init = 123.; doubLe ****array; /* Test 1 */ if ( (array = (doubLe ****) daav(sizeof(doubLe), 4, d, st, &err_code, &free-ptr, NULL)) == NULL ) { pr intf("daav: error on dynamic aLLocation. %s\n", daa_errs[err_code]); } The fi rst argument to daavO and daa 0 is the size of tJl e basic obj ect being addres ed in the array- almost always calculated wi th tile sizeofO operator. The econd argument is me maximum dimension. The mird and fourth arguments are the dimensional exten t and start subsc ript of each dimensio n in order, from left to right. The fiftll argument is th e returned error code. This wi ll be set, like errno, only if an error occurs and indexes the daa_errs[] a n-ay avai lable glo ba lly from daa. h. The sixm argument is, fo r daavO, a free pointer used to deallocate the array. Do not use free(array) to free the allocation. This will resul t in an elTor, as the array poin ter does not poil1l to the start of the vaLLocOed memory area. Fo r daaO, a base poin t- er to the caller-allocated memory is passed for daaO to ini tialize wi th linked pointers. The caller deallocates with free(base-ptr). Initializatio n can eimer be NULL fo r no ne , o r the cast-to-pointer add ress of a type me same as that used ·as an argument to sizeofO in me fi rst argument. In tile case of daaO it helps to know how much space to allocate in tile callel-. This is calculated by a call to dasO (dynamic array size) and then passed to rna L LocO. Notice in both Embedded Syst ems Programming DECEMBER 2000 153 asize = das(sizeof(doubLe), 4, d, &err_code); base-ptr = (char *)maLLoc(asize); if ( (array = (doubLe ****) daa(sizeof(doubLe), 4, d, st, &err_code, base-ptr, (char *)&init)) == NULL { pri ntf( "daa: error on dynami c aLLocation. %s\n", daa_errs[err_code]); } ... ~ o L ... o o c ~ ~

Articles in this issue

Archives of this issue

view archives of EETimes - Embedded Systems December 2000 Vol13_13