I practiced an array of strings with no initial values.
Attempt 1
#include <stdio.h>
char *array[] = {};
int main(int argc, char *argv[]) {
array[0]="Hello";
array[1]="World";
char **i = array;
while (*i) {
printf("%d %s\n", i, *i);
i++;
}
}
$ gcc array_of_strings.c && ./a.out
6293704 Hello
6293712 World
It works fine.
Attempt 2
I thought I could move array pointer inside main function.
#include <stdio.h>
int main(int argc, char *argv[]) {
char *array[] = {};
array[0]="Hello";
array[1]="World";
char **i = array;
while (*i) {
printf("%d %s\n", i, *i);
i++;
}
}
$ gcc array_of_strings.c && ./a.out
-1899140568 (j͎?
-1899140560 World
-1899140552 ???%Y
-1899140544 1?I??^H??H???PTI???@
-1899140536 d?͎?
Segmentation fault
Huh, why it is not working? It causes “Segmentation fault” with ugly output.
Could somebody explain why I should not do this way?
Two problems.
You aren’t allocating space for the array items. With your empty initializer list you are allocating an empty array. When you write to
array[0]andarray[1]you are writing to memory you do not own.You are getting lucky when you allocate the array globally. Global (aka statically-allocated) memory blocks tend to be filled with zeros. This is good for you because your
whileloop depends on their being a NULL pointer at the end of the array.When you allocate on the stack and access memory past the end of the array you will get whatever happens to already be on the stack, which can be any arbitrary garbage. Your
while (*i)loop doesn’t get the NULL pointer it expects so it will keep on reading the garbage data until it finds some zeros that look like a NULL pointer.To fix #1, give an explicit length to the array. To fix #2, you must explicitly add a NULL pointer to the end of the array.
Also, for what it’s worth, pointers aren’t guaranteed to be the same size as
ints. It is better to use%pto print pointers rather than%d.