//every malloc needs exactly one free
//a leak: the pointer is overwritten and the first block is lost,
//nothing can free it now (a leak on purpose, for the lesson)
int *numbers = malloc(3 * sizeof *numbers);
numbers = malloc(5 * sizeof *numbers);
free(numbers);
//without the leak: free the old block before the pointer gets a new one
int *values = malloc(3 * sizeof *values);
free(values);
values = malloc(5 * sizeof *values);
free(values);
char *name = strdup("Alice");
//name is "Alice"
printf("name is %s\n", name);
//a double free crashes the program:
//free(name); free(name); //<-Error
//so after free the pointer gets nullptr: free(nullptr) does nothing
free(name);
name = nullptr;
free(name);
//name is nullptr
//reading name[0] after free is an error too;
//with nullptr it at least fails at once
printf("name is %s\n", name == nullptr ? "nullptr" : "set");