Это не невозможно реализовать сборщик мусора для C (и на самом деле они существуют, как показывает простой поиск в Google ), это просто сложно, потому что это может быть Трудно определить, является ли определенная строка битов указателем на выделенный блок или просто выглядит как единица.
Причина, по которой это является проблемой, заключается в том, что C (и C ++, в этом отношении) позволяет вам приводить тип указателя к целочисленному типу, поэтому целочисленная переменная может содержать адрес в выделенном блоке, предотвращая GC от освобождение этого блока, даже если это значение не предназначено для указателя.
Например, допустим, у меня выделен блок памяти. Предположим, что этот блок памяти выделен, начиная с адреса 0x00100000 (1 048 576), и имеет длину 1 МБ, поэтому расширяется до 0x001FFFFF (2 097 151).
Допустим, я также сохраняю размер файла изображения в переменной (назовем это fileSize). Размер этого файла изображения составляет 1,5 МБ (1 572 864 байта).
Таким образом, при запуске сборщика мусора он встретит мою переменную fileSize
, найдет ее, содержащую значение, соответствующее адресу в моем выделенном блоке, и решит, что он не может освободить этот блок, чтобы он не сделал недействительным мой указатель Maybe. , Это потому, что сборщик мусора не знает, сделал ли я это:
int fileSize;
{
char *mem = (char*)malloc(1048576);
fileSize = (int)(mem + 524288);
}
// say GC runs here
или, если я только что сделал это:
int fileSize;
{
char *mem = (char*)malloc(1048576);
fileSize = 1572864;
}
// say GC runs here;
В последнем случае безопасно освободить блок в * mem, (если нет других ссылок), тогда как в первом это не так. Он должен быть консервативным и предполагать, что это не так, поэтому память «протекает» (по крайней мере до тех пор, пока fileSize не выйдет из области или не изменится на значение вне выделенного блока).
Но сборщики мусора для C (и C ++) do существуют. Являются ли они ценными, вопрос другого обсуждения.