Вы возвращаете указатель на локальную переменную в этом случае:
//if current node is exact size and hasn't been used it return the x,y of the mid-point of the rectangle
if (w==node->width && h == node->height) {
node->used=1;
rp.x = node->x+(w/2);
rp.y = node->y+(h/2);
p = &rp;
return p;
}
Это большой нет-нет . Локальная переменная больше не действительна после возврата функции, поэтому возвращаемый вами указатель указывает на стековую память, которая теперь потенциально используется для чего-то другого. Когда вы начинаете что-то делать с этим, вы повреждаете свой стек, и ваша программа начинает работать очень хаотично.
Чтобы это исправить, вам нужно выполнить одно из следующих действий: (1) иметь recursiveFind()
возвращать PackNode
по значению вместо указателя на PackNode
; (2) использовать глобальный / статический PackNode
экземпляр и вернуть на него указатель (обратите внимание, что тогда это делает recursiveFind()
не-поточно-безопасным); или (3) вернуть указатель на динамически распределенный экземпляр PackNode
(например, выделенный с malloc()
); тогда для этого требуется, чтобы вызывающий recursiveFind()
вызывал free()
на возвращенном указателе в более поздний момент, когда он больше не нужен.
Аналогично, этот код также неверен:
//If rectangle wasn't exact fit, create branches from cloning it's parent.
PackNode l_clone = _clone(node);
PackNode r_clone = _clone(node);
node->left = &l_clone;
node->right = &r_clone;
Вам нужно разместить l_clone
и r_clone
в куче, а не в стеке, потому что, опять же, как только эта функция вернется, эти node
указатели больше не будут действительными. Я бы рекомендовал, чтобы _clone()
возвращал указатель на PackNode
(выделенный с malloc()
) вместо полного PackNode
объекта по значению. Однако, если вы это сделаете, вызывающему коду нужно знать, чтобы вызвать free()
в возвращенном указателе в какой-то более поздний момент, когда объект больше не нужен.
[Кроме того, идентификаторы в глобальной области видимости, начинающиеся с подчеркивания, зарезервированы реализацией, поэтому вам следует избегать использования таких имен; Вы должны переименовать _clone()
в что-то вроде clone()
или clonePackNode()
].