Если вы Google EXC_BAD_ACCESS
, вы обнаружите, что это потому, что вы обращаетесь к памяти за пределами выделенного блока памяти.Это может быть по нескольким причинам.
Итак, давайте начнем с точки сбоя - memcpy
: вы пишете свободному указателю (&free
) содержимое свободного (free
),и копируем sizeof(char *)
байтов.Если предположить, что free объявлено как char *free;
, тогда это нормально, поэтому это должно быть содержимое free
, с которого вы пишете.
Стилистически, используя memcpy
, как это - для копирования значения одного указателя- сбивает с толку.Вам лучше что-то вроде:
free = *(char **)free;
, что эквивалентно вашему:
memcpy(&free,free,sizeof(char*));
Значение sizeof(char*)
варьируется в зависимости от системы - 4
на 32-битнойи 8
на 64-битной - поэтому объем выделенного пространства должен быть как минимум настолько большим.
Хорошо, поэтому давайте посмотрим на метод expandPool, чтобы увидеть, что для free установлено в:
tmp2 = new char;
Здесь вы выделяете блок памяти с sizeof(char)
, равным 1
.Это должно быть как минимум:
tmp2 = new char[sizeof(char *)];
ПРИМЕЧАНИЕ. Вызов вашей переменной free
переопределит функцию free
, поэтому вам нужно будет явно обратиться к этой функции, написав ::free
.
Я начну с того, что нарисую диаграмму того, какой должна быть структура памяти пула, и как она будет выглядеть / изменяться (а), когда пусто, (б) при выделении свободного чанка и (с)) при выделении чанка, когда вам нужно расширить пул.Пометьте диаграмму различными переменными (pool
, tmp
, tmp2
и free
).Это даст вам представление о том, что вам нужно делать и как должен выглядеть код.
Хорошее понимание структур данных и алгоритмов (путем создания диаграмм) поможет вам правильно понять код.