char carrot[50][256];
This reserves the 256 characters for each of the fifty strings, even if in practice some of them are only
one or two bytes long. If you do this a lot, it can be wasteful of memory. One alternative is to use an
array of pointers-to-strings, and note that the second level arrays don't all have to be the same size, as
shown in Figure 10-4.
Figure 10-4. A Ragged String Array
If you declare an array of pointers to strings, and allocate memory for these strings as needed, you will
be much more frugal with machine resources. Some people call these "ragged arrays" because of the
uneven right-hand ends. You can create one by filling the Iliffe vector with pointers to strings which
already exist, or by allocating memory for a fresh copy of the string. Both of these approaches are
shown in Figure 10-5.
Figure 10-5 Creating a Ragged String Array
char * turnip[UMPTEEN];
char my_string[] = "your message here";
/ share the string / / copy the string /
turnip[i] = &my_string[0]; turnip[j] =
malloc( strlen(my_string)
+ 1 );
strcpy(turnip[j], my_string);
Wherever possible with strings, don't make a fresh copy of the entire string. If you need to reference it
from two different data structures, it's much faster and uses less store to duplicate the pointer, not the
string. Another performance aspect to consider is that Iliffe vectors may cause your strings to be
allocated on different pages in memory. This could detract from locality of reference and cause more
paging, depending on how, and how frequently, you reference the data.
Handy Heuristic