{"action":"opened","issue":{"url":"https://api.github.com/repos/orangeduck/BuildYourOwnLisp/issues/81","labels_url":"https://api.github.com/repos/orangeduck/BuildYourOwnLisp/issues/81/labels{/name}","comments_url":"https://api.github.com/repos/orangeduck/BuildYourOwnLisp/issues/81/comments","events_url":"https://api.github.com/repos/orangeduck/BuildYourOwnLisp/issues/81/events","html_url":"https://github.com/orangeduck/BuildYourOwnLisp/issues/81","id":53351532,"number":81,"title":"Printing Expressions","user":{"login":"nohwnd","id":5735905,"avatar_url":"https://avatars.githubusercontent.com/u/5735905?v=3","gravatar_id":"","url":"https://api.github.com/users/nohwnd","html_url":"https://github.com/nohwnd","followers_url":"https://api.github.com/users/nohwnd/followers","following_url":"https://api.github.com/users/nohwnd/following{/other_user}","gists_url":"https://api.github.com/users/nohwnd/gists{/gist_id}","starred_url":"https://api.github.com/users/nohwnd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nohwnd/subscriptions","organizations_url":"https://api.github.com/users/nohwnd/orgs","repos_url":"https://api.github.com/users/nohwnd/repos","events_url":"https://api.github.com/users/nohwnd/events{/privacy}","received_events_url":"https://api.github.com/users/nohwnd/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-01-04T22:41:33Z","updated_at":"2015-01-04T22:41:33Z","closed_at":null,"body":"Hello I am following the code in the book and in this chapter I am getting ```Segmentation fault: 11```, I read on the internet that is caused by uninitialized access to data. I went through the code in the book few times and I can't spot the error. Could you check my code please? \r\nThis is the output from ```LLDB```:\r\n```\r\nnbook:repl nohwnd$ lldb ./program \r\n(lldb) target create \"./program\"\r\nCurrent executable set to './program' (x86_64).\r\n(lldb) run\r\nProcess 5671 launched: './program' (x86_64)\r\nLispy Version\r\nPress Ctrl+C to exit\r\n\r\nlispy> + 2 2\r\nProcess 5671 stopped\r\n* thread #1: tid = 0x34b02, 0x0000000100001164 program`lval_add + 20, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x20)\r\n    frame #0: 0x0000000100001164 program`lval_add + 20\r\nprogram`lval_add + 20:\r\n-> 0x100001164:  movl   0x20(%rsi), %eax\r\n   0x100001167:  addl   $0x1, %eax\r\n   0x10000116c:  movl   %eax, 0x20(%rsi)\r\n   0x10000116f:  movq   -0x8(%rbp), %rsi\r\n```\r\nThe problem is likely in ```lval_read``` where NULL is assigned to x pointer. If I change that line to ```lval* x = lval_sexpr();``` the code works correctly.\r\n\r\nThis is my full code:\r\n```c\r\n#include \"mpc.h\"\r\n\r\n/* if we compile on windows compile these functions */\r\n#ifdef _WIN32\r\n  #include <string.h>\r\n\r\n  static char buffer[2048];\r\n\r\n  /* fake readline function */\r\n  char* readline (char* prompt) {\r\n    fputs(prompt, stdout);\r\n    fgets(buffer, 2048, stdin);\r\n    char* cpy = malloc(strlen(buffer)+1);\r\n    strcpy(cpy, buffer);\r\n    cpy[strlen(cpy)-1] = '\\0';\r\n\r\n    return cpy;\r\n  }\r\n\r\n  /*fake history function*/\r\n  void add_history(char*) {}\r\n#else\r\n  /*compiling on mac */\r\n  #include <editline/readline.h>\r\n#endif\r\n\r\ntypedef struct lval {\r\n  int type;\r\n  long num;\r\n  /* Errors and Symbols have some string data */\r\n  char* err;\r\n  char* sym;\r\n\r\n  int count;\r\n  struct lval** cell;\r\n} lval;\r\n\r\n/* Possible lval types */\r\nenum { LVAL_ERR, LVAL_NUM, LVAL_SYM, LVAL_SEXPR };\r\n\r\n/* Possible error types */\r\nenum { LERR_DIV_ZERO, LERR_BAD_OP, LERR_BAD_NUM };\r\n\r\n/* Add lval as a child to SExpression */\r\nlval* lval_add(lval* v, lval* x) {\r\n  v->count++;\r\n  v->cell = realloc(v->cell, sizeof(lval*) * v->count);\r\n  v->cell[v->count-1] = x;\r\n\r\n  return v;\r\n}\r\n\r\n/* Create pointer to new Number lval */\r\nlval* lval_num(long x) {\r\n  lval* v = malloc(sizeof(lval));\r\n  v->type = LVAL_NUM;\r\n  v->num = x;\r\n\r\n  return v;\r\n}\r\n\r\n/* Create pointer to new Error val */\r\nlval* lval_err(char* m) {\r\n  lval* v = malloc(sizeof(lval));\r\n  v->type = LVAL_ERR;\r\n  v->err = malloc(strlen(m) + 1);\r\n  strcpy(v->err, m);\r\n\r\n  return v;\r\n}\r\n\r\n/* Create pointer to new Symbol lval */\r\nlval* lval_sym(char* s) {\r\n  lval* v = malloc(sizeof(lval));\r\n  v->type = LVAL_SYM;\r\n  v->sym = malloc(strlen(s) + 1);\r\n  strcpy(v->sym, s);\r\n\r\n  return v;\r\n}\r\n\r\n/* Create pointer to new empty SExpression lval */\r\nlval* lval_sexpr(void) {\r\n  lval* v = malloc(sizeof(lval));\r\n  v->type = LVAL_SEXPR;\r\n  v->count = 0;\r\n  v->cell = NULL;\r\n\r\n  return v;\r\n}\r\n/* Delete the lval and all it linked fields */\r\nvoid lval_del(lval* v) {\r\n  switch(v->type) {\r\n    /* Do nothing special for number type */\r\n    case LVAL_NUM:\r\n      break;\r\n    case LVAL_ERR:\r\n      free(v->err);\r\n      break;\r\n    case LVAL_SYM:\r\n      free(v->sym);\r\n      break;\r\n    case LVAL_SEXPR:\r\n      for (int i = 0;  i < v->count; i++) {\r\n        lval_del(v->cell[i]);\r\n      }\r\n      /* Free the memory allocated to hold the pointers as well */\r\n      free(v->cell);\r\n      break;\r\n  }\r\n\r\n  free(v);\r\n}\r\n\r\nlval* lval_read_num(mpc_ast_t* t) {\r\n  errno = 0;\r\n  long x = strtol(t->contents, NULL, 10);\r\n  return errno != ERANGE ? lval_num(x) : lval_err(\"Invalid number\");\r\n}\r\n\r\nlval* lval_read(mpc_ast_t* t) {\r\n  /* If Symbol or Number return conversion to that type */\r\n  if (strstr(t->tag, \"number\")) { return lval_read_num(t);}\r\n  if (strstr(t->tag, \"symbol\")) { return lval_sym(t->contents); }\r\n  /* If root (>) or sexpr then create empty list */\r\n  lval* x = NULL;\r\n  //lval* x = lval_sexpr();\r\n  if(strstr(t->tag, \">\") == 0) { x = lval_sexpr(); }\r\n  if(strstr(t->tag, \"sexpr\")) { x = lval_sexpr(); }\r\n\r\n  /* Fill this list with any valid expression contained within */\r\n  for ( int i = 0; i < t->children_num; i++) {\r\n    if (strcmp(t->children[i]->contents, \"(\") == 0 ) { continue; }\r\n    if (strcmp(t->children[i]->contents, \")\") == 0 ) { continue; }\r\n    if (strcmp(t->children[i]->contents, \"}\") == 0 ) { continue; }\r\n    if (strcmp(t->children[i]->contents, \"{\") == 0 ) { continue; }\r\n    if (strcmp(t->children[i]->tag, \"regex\") == 0 ) { continue; }\r\n\r\n    x = lval_add(x, lval_read(t->children[i]));\r\n  }\r\n\r\n  return x;\r\n}\r\n\r\n/* Forward define funciton that has circular reference */\r\nvoid lval_expr_print(lval* v, char open, char close);\r\n\r\n/* Print an lval */\r\nvoid lval_print(lval* v) {\r\n  switch (v->type) {\r\n    /* In case the type is a number print it */\r\n    /* Then break out of the switch */\r\n    case LVAL_NUM:\r\n      printf (\"%li\", v->num);\r\n      break;\r\n\r\n    /* In case the type is error find what error\r\n    it is and print it */\r\n    case LVAL_ERR:\r\n      printf(\"Error: %s\", v->err);\r\n      break;\r\n    case LVAL_SYM:\r\n      printf(\"%s\", v->sym);\r\n      break;\r\n    case LVAL_SEXPR:\r\n      lval_expr_print(v,'(', ')');\r\n      break;\r\n  }\r\n}\r\n\r\nvoid lval_println(lval* v) {\r\n  /* Print lval followed by new line */\r\n  lval_print(v);\r\n  putchar('\\n');\r\n}\r\n\r\nvoid lval_expr_print(lval* v, char open, char close) {\r\n  putchar(open);\r\n  for (int i = 0; i < v->count; i++) {\r\n    lval_print(v->cell[i]);\r\n\r\n    /* Don't print trailing space if this is the last element */\r\n    if (i != (v->count-1)) {\r\n      putchar(' ');\r\n    }\r\n  }\r\n  putchar(close);\r\n}\r\n\r\nint main (int argc, char** argv) {\r\n  /* Create some parsers */\r\n  mpc_parser_t* Number        = mpc_new(\"number\");\r\n  mpc_parser_t* Symbol        = mpc_new(\"symbol\");\r\n  mpc_parser_t* SExpression   = mpc_new(\"sexpression\");\r\n  mpc_parser_t* Expression    = mpc_new(\"expression\");\r\n  mpc_parser_t* Lispy         = mpc_new(\"lispy\");\r\n\r\n  /* Define the with the following language */\r\n  mpca_lang(MPCA_LANG_DEFAULT,\r\n  \"number: /-?[0-9]+/; \\\r\n  symbol: '+'|'-'|'*'|'/'; \\\r\n  sexpression: '(' <expression>* ')'; \\\r\n  expression: <number> | <symbol> | <sexpression>; \\\r\n  lispy: /^/ <expression>* /$/;\",\r\n  Number, Symbol, SExpression, Expression, Lispy);\r\n\r\n\r\n  /*Print Version and Exit information*/\r\n  printf(\"Lispy Version\\n\");\r\n  puts(\"Press Ctrl+C to exit\\n\");\r\n\r\n  mpc_result_t r;\r\n\r\n  /*In neverending loop */\r\n  while(1){\r\n    /*output our prompt and get input*/\r\n    char* input = readline(\"lispy> \");\r\n    /*Add input to history*/\r\n    add_history(input);\r\n\r\n    if (mpc_parse(\"<stdin>\", input, Lispy, &r))\r\n    {\r\n      lval* x = lval_read(r.output);\r\n      lval_println(x);\r\n      lval_del(x);\r\n    }\r\n    else{\r\n      /*Ohterwise print the error */\r\n      mpc_err_print(r.error);\r\n      mpc_err_delete(r.error);\r\n    }\r\n\r\n    free(input);\r\n  }\r\n\r\n  /* Undefine and delete the parsers */\r\n  mpc_cleanup(4, Number, Symbol, SExpression, Expression, Lispy);\r\n  return 0;\r\n}\r\n```"}}