ポインタ理解の為の習作

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

typedef struct namelist {
  char *word;
  struct namelist *next;
  struct namelist *prev;
} namelist;

namelist *get_list(namelist *(*set_list)(char **, int))
{
  int i;
  char **str_store, tmp_str[64];
  str_store = (char **)malloc(sizeof(char *));
  *str_store = (char *)malloc(64);
  for(i = 0; scanf("%s", &tmp_str) != EOF; i++) {
	strcpy(*(str_store + i), tmp_str);
	str_store = (char **)realloc(str_store, (i + 2) * sizeof(char *));
	*(str_store + i + 1) = (char *)malloc(64);
  }
  free(*(str_store + i));
  str_store = (char **)realloc(str_store, i * sizeof(char *));
  return (*set_list)(str_store, i);
}

namelist *set_to_list(char **str_store, int max)
{
  int i;
  namelist *obj = (namelist *)malloc(sizeof(namelist) * max);
  for(i = 0; i < max; i++) {
	(obj+i)->word = *(str_store + i);
	(obj+i)->next = obj + i + 1;
	(obj+i)->prev = obj + i - 1;
  }
  obj->prev = (obj+i-1)->next = obj;
  free(str_store);
  return obj;
}

void set_it_free(namelist *list)
{
  namelist *tmp = list;
  do {
	free(list->word);
  } while((list = list->next) != tmp);
  free(list);
}

int main(int argc, char **argv)
{
  namelist *list, *tmp;
  list = tmp = get_list(set_to_list);
  do {
	printf("%s\n", list->word);
  } while((list = list->next) != tmp);
  set_it_free(list);
  return 0;
}

 配列とポインタの関係がだいたい理解できたので(勿論、「基礎的な」という枕詞付き)、関数ポインタまで手を出してみた。関数ポインタについてはJavaScriptに触れてたおかげで、シンタックス以外では特に悩むことがなくなってた。