In C, an array of characters is not string; instead, C-string should end with \0, like HelloWorld in C is {'H','e','l','l','W','o','r','l','d','\0'}
If, however, we did not allocate enough space for the \0 char, like the code block 1 (5 char long is not enough for three, seven, and eight), the output will mix up

// Block 1
char str[9][5] = {"one", "two", "three", "four", "five", "six", "seven","eight", "nine"};
for(int i = 0; i < 9; i++)
printf("%s\n", str[i]);

// Output
one
two
threefour
four
five
six
seveneightnine
eightnine
nine


Notice that the output mixed up when printing three, seven, and eight, which I assume is that printf will finish extracting chars from a char pointer when it encounter \0. In this case, three, seven, and eight do not have \0. In fact, what three stores in the memory is something likes this: {'t','h','r','e','e','f','o','u','r','\0'}. The printf function will not stop until it meet with the first \0, which is at the end of four, thus causes mixed output.

Portal to StackOverflow on similar issue