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.
s
is 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, ands
has 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
&s
and&family2[0]
are NOT equal. Thus, adding one to&s
will 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
&s
is constant throughout all iterations of our loop. This is the cause of the observed infinite loop.
Thanks to EVERYONE for their help!
lifecrisis