Pointer to pointer style 2D arrays work very differently than "straight" 2D arrays illustrated above. Straight 2D arrays are stored consecutively in memory, whereas pointer-to-pointer arrays are scattered throughout memory, with an EXTRA array of pointers to tell you where each item is.
Let's look at a typical p-to-p style array:
1 2 3 4 5 6 7 8 9
|
char** p = new char*[3];
p[0] = new char[10];
p[1] = new char[10];
p[2] = new char[10];
strcpy(p[0], "one");
strcpy(p[1], "two");
strcpy(p[2], "three");
|
Notice that there are 4 calls to new[] here (once for p, and then one for each p[0],p[1], and p[2]). This means we have 4 individual arrays. We do not have one giant array as we did above. These 4 individual arrays can (and likely will be) scattered across memory in an unpredictable fashion. So memory may look something like this:
1 2 3 4 5 6
|
.....two_______............one_______........002700050064.......three_____.
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | | | | | | | | |
| 05 | 15 | 25 | 35 | 45 | 55 | 65 | 75
0 10 20 30 40 50 60 70
|
Here, the dots are unallocated memory (stuff we can't use / don't care about). Underscores are still null characters in the string, same as the previous example. But notice there's that clump of numbers at address 45. That's our 'p' array. It's an array of pointers, telling us where each of our other arrays are in memory.
For purposes of this example, I have shown each pointer as 4 digits: '0027', '0005' and '0064'. You'll notice that those represent the locations of the "one", "two", and "three" strings respectively.
Now to step through this array, we can use a pointer to a pointer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
char** name_ptr = p; // same as name_ptr = &p[0].
// name_ptr points to example address 0045.
printf("%s ", *name_ptr);
// here, *name_ptr uses the * dereference operator. This will have the computer
// look at the memory pointed to by name_ptr.
// name_ptr points to address 0045. If we read from address 0045, we get a value of 0027,
// which is the location of the 'one' string. Therefore this will print "one"
name_ptr++; // by incrementing name_ptr, it now points to p[1].. or address 0049
printf("%s ", *name_ptr);
// same deal. Computer will read from address 0049, getting a value of 0005... the location
// of our 'two' string. So this will print "two"
// ... and so on for the 3rd string
|