Grab the unsafe.c example and compile it:

cp ~cs50/examples/unsafe.c .
mygcc -o unsafe unsafe.c -lpthread

Here is the code:

/* 
 * unsafe.c: a demonstration of unsafe threads
 * 
 * usage: ./unsafe
 * 
 * CS50, Summer 2020
 */

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

/*********** global variables ************/
char s1[] = "abcdefg";
char s2[] = "xyz";
char* c;

/*********** function prototypes ************/
void* aa(void *ptr); 
void last_letter(char* a, int i); 

/*********** main ************/
int main() {
  pthread_t t1;
  int iret1 = pthread_create(&t1, NULL, aa, NULL);
  if (iret1) {
    fprintf(stderr,"Cannot create thread, rc=%d\n", iret1);
  }
  last_letter(s1, 3);
  printf("Ended nicely this time\n");
  return 0; //never reached when c = NULL is not commented out.
}

// thread t1's function
void* aa(void *ptr) {
  last_letter(s2, 1);
  return NULL;
}

// This function will run concurrently
void last_letter(char* a, int i) {
  printf("last_letter ( a is %s and i is %d)\n", a, i);
  sleep(i);
  //c = NULL;   // uncomment out, what is different?
  sleep(i);
  c = a;
  sleep(i); 
  while (*c) {
    c++;
  }
  printf("%c\n", *(c-1));
}

And here’s the output, first with the c = NULL commented out, and then with it not commented out.

# comment out the "c = NULL;" line
$ ./unsafe
last_letter ( a is abcdefg and i is 3)
last_letter ( a is xyz and i is 1)
z
g
Ended nicely this time

# uncomment the "c = NULL;" line
$ ./unsafe
last_letter ( a is abcdefg and i is 3)
last_letter ( a is xyz and i is 1)
Segmentation fault (core dumped)
$ 

Discuss with your team members. Can you explain what happened?