APPENDIX: Dynamic Data Arrays

Introduction and Warning

I don't expect you to use this section as anything other than a rough guide. This is what I use to describe my own layout. Yours is surely different. You need to see, however, how I initialize my data arrays, first to all zeroes and nulls, then how I specify my layout hardware. You won't be copying this unless you like some heavy cut-and-paste action, but it might be helpful to see how the details are done.

Please pardon the fact that it, too, is a work in progress. As array structure gets changed during further program development, this stuff too will change. I'll try to update it from time to time but, as they say, "Caveat emptor."

WARNING: This is undergoing a major revision as of March, 2021, to become dynamic (resizable) data arrays. I'll try to update it occasionally, and mark it where changed, but beware!

How in the World Can You Edit This Stuff?

Lurking in the back of my mind has long been a worry, and it's a bit like the old cartoon trope: a clown hides behind a sapling. He's a couple of feet wide, yet the sapling is at most an inch wide. How does he do it? ...and what if there's a bear in there?

Well, in the early motion picture and television shows, they used a portion of canvas scenery backdrop, painted or glued a sapling on its edge, and thanks to movie and television pictures being black-and-white, low-resolution, two-dimensional images, the clown could walk behind the edge and, being behind the set backdrop, seem to disappear. It was called "the magic of television," and it was (and still is) pretty cheesy.

So, here lurks a "bear in the woods." Standard C has no means of re-sizing arrays dynamically. In order to do it, it is necessary to rename an old array, allocate memory for a newer, larger array of the same name, then copy the old array's elements into the new one. Later versions such as C++, C#, et cetera had built-in array resizing, but in this code, there's no such luck. ...or at least, not until you write your own. Easy, right? Yeah. Right. The problem is, if you iterate through an array, allocating and storing, allocating and storing, the array's elements won't be contiguous so you can't address the elements with subscripts. "Oh, what to do?"

The answer is to allocate memory for the whole of an array all at once. Typically you describe the array as a struct or typedef, then use

(typecast) new_array*=(typecast)calloc(1,sizeof(array));

void *calloc(size_t nitems, size_t size)

which makes, out in memory somewhere, the new array and stores a pointer to it or, for an array of elements, you can use

(typecast) new_array* =(typecast)calloc(nmbr_elements,nmbr_elements*sizeof(array)));

where the individual elements in the new array can be addressed as element[0] through element[nmbr_elements-1]. Using "calloc" instead of "malloc" initializes the whole array to zeroes, which costs a little run time but is unimportant during initialization. So, to give a less abstract example, an array of ten integers can be generated by

(int*)int_array = (int*)calloc(10,sizeof(int));

and an individual element such as #5 can be stored by

int_array[5] = 67;

or conversely, read by

(int) int_amount=int_array[5];

What is really nice is that this can be done programmatically, as opposed to at compile time, leading to the ability to edit program structure "on the fly." That's coming in the near future. In the mean time, though, there's another issue or three: run-time storing or retrieving key variable values in files. This feature is here now, as of this writing, for the most part. Some of the software structures present daunting challenges, such as how to store and retrieve instructions for drawing the layout diagram, particularly the parts that use GLADE graphics. This can be done programmatically, using the "Cairo" graphics package, but that may require abandoning GLADE usage. We'll see.