While experimenting with methods for stepping through an array of strings in C, I developed the following small program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char* string;
int main() {
char *family1[4] = {"father", "mother", "son", NULL};
string family2[4] = {"father", "mother", "son", NULL};
/* Loop #1: Using a simple pointer to step through "family1". */
for (char **p = family1; *p != NULL; p++) {
printf("%s\n", *p);
}
putchar('\n');
/* Loop #2: Using the typedef for clarity and stepping through
* family2. */
for (string *s = family2; *s != NULL; s++) {
printf("%s\n", *s);
}
putchar('\n');
/* Loop #3: Again, we use the pointer, but with a unique increment
* step in our for loop. This fails to work. Why? */
for (string s = family2[0]; s != NULL; s = *(&s + 1)) {
printf("%s\n", s);
}
}
My specific question involves the failure of Loop #3. When run through the debugger, Loops #1 and #2 complete successfully, but the last loop fails for an unknown reason. I would not have asked this here, except for the fact that is shows me that I have some critical misunderstanding regarding the "&" operator.
My question (and current understanding) is this:
family2 is an array-of-pointer-to-char. Thus, when s is set to family2[0] we have a (char*) pointing to "father". Therefore, taking &s should give us the equivalent of family2, pointing to the first element of family2 after the expected pointer decay. Why doesn't, then,
*(&s + 1) point to the next element, as expected?
Many thanks,
lifecrisis
EDIT -- Update and Lessons Learned:
The following list is a summary of all of the relevant facts and interpretations that explain why the third loop does not work like the first two.
sis a separate variable holding a copy of the value (a pointer-to-char) from the variablefamily2[0]. I.e., these two equivalent values are positioned at SEPARATE locations in memory.family2[0]up tofamily2[3]are contiguous elements of memory, andshas no presence in this space, though it does contain the same value that is stored infamily2[0]at the start of our loop.- These first two facts mean that
&sand&family2[0]are NOT equal. Thus, adding one to&swill return a pointer to unknown/undefined data, whereas adding one to&family2[0]will give you&family2[1], as desired. - In addition, the update step in the third for loop doesn't actually result in s stepping forward in memory on each iteration. This is because
&sis constant throughout all iterations of our loop. This is the cause of the observed infinite loop.
Thanks to EVERYONE for their help!
lifecrisis