#include <stdlib.h>
#include <stdio.h>

int main()
{
  /* The compiler allocates space for "Hello" and '\0' (5 + 1 chars)
   * and stores the address in aString1.
   */
  const char *aString1 = "Hello";
  /* The compiler allocates 10 chars and initializes
   * it with "World" (and the '\0' for terminator).
   */
  const char aString2[10] = "World";
  /* The compiler determines length of initializer "I'm here."
   * (9 + 1) and allocates the array of appropriate size.
   */
  const char aString3[] = "I'm here.";
  /* allocate storage for array (3 const char*) */
#if 0 /* the usual way */
  const char **array = malloc(3 * sizeof (const char*));
#else /* how Matheus wants to do it */
  const char **array = NULL;
  array = realloc(array, 3 * sizeof (const char*));
#endif /* 0 */
  /* assign contents (using it like an array) */
  array[0] = aString1;
  array[1] = aString2;
  array[2] = aString3;
  /* apply array to another variable array2 */
  const char **array2 = array; /* assigns the address only */
  /* use it: */
  printf("array2[0]: '%s', array2[1]: '%s', array2[2]: '%s'\n",
    array2[0], array2[1], array2[2]);
  /* throw away storage of array (and array2) */
  free(array);
  /* Attention! array, array2 become wild pointers at this point
   * and may not be accessed (except new, valid addresses are assigned).
   * However, aString1, aString2, aString3 are still intact.
   */
  printf("aString1: '%s', aString2: '%s', aString3: '%s'\n",
    aString1, aString2, aString3);
  /* done */
  return 0;
}
