CS50 автоматически управляет собственной памятью.
Перед основным libcs50 регистрируется atexit
обратный вызов в cs.50: 449 :
/**
* Called automatically before execution enters main.
*/
INITIALIZER(setup)
{
// Disable buffering for standard output
setvbuf(stdout, NULL, _IONBF, 0);
atexit(teardown);
}
Функция teardown()
освобождает всю память, выделенную libcs50:
static void teardown(void)
{
// Free library's strings
if (strings != NULL)
{
for (size_t i = 0; i < allocations; i++)
{
free(strings[i]);
}
free(strings);
}
}
Где strings
- глобальный объект в cs50.c: 67 .
Когда вы free(name)
, указатель за именем также сохраняется в strings[0]
(присваивается в get_string()
).
После выхода main()
выполняется зарегистрированный обратный вызов atexit
и выполняется free(strings[0])
, который пытается освободить объект вдвое.