tl; dr: справа не в тому, що динамічне розподіл пам'яті за своєю суттю не є детермінованим (як ви визначили це з точки зору ідентичних шляхів виконання); це те, що це, як правило, робить вашу програму непередбачуваною . Зокрема, ви не можете передбачити, чи може розподілювач не спрацювати перед довільною послідовністю входів.
Ви можете мати недетермінований розподільник. Це насправді поширене поза вашим реальним часом, коли операційні системи використовують такі речі, як рандомізація розташування адрес. Звичайно, це зробить вашу програму недетермінованою.
Але це не цікавий випадок, тому припустимо ідеально детермінований розподільник: однакові послідовності розподілів та вивільнення завжди матимуть однакові блоки в одних і тих самих місцях, і ці розподіли та вивільнення завжди матимуть обмежений час роботи.
Тепер ваша програма може бути детермінованою: однаковий набір входів призведе до абсолютно однакового шляху виконання.
Проблема полягає в тому, що якщо ви розподіляєте та звільняєте пам’ять у відповідь на входи, ви не можете передбачити, чи розподіл коли-небудь провалиться (і помилка не є варіантом).
По-перше, ваша програма може втратити пам’ять. Отже, якщо йому потрібно працювати необмежено довго, врешті-решт розподіл не вдасться.
Але навіть якщо ви можете довести, що немає витоків, вам слід знати, що ніколи не існує послідовності введення, яка могла б вимагати більше пам'яті, ніж доступно.
Але навіть якщо ви можете довести, що програмі ніколи не буде потрібно більше пам'яті, ніж доступно, розподільник може, залежно від послідовності розподілів і звільнень, фрагментувати пам'ять і, отже, врешті-решт не зможе знайти суміжний блок для задоволення розподілу, навіть незважаючи на те, що в цілому достатньо вільної пам'яті.
Дуже важко довести, що немає послідовності входів, яка призвела б до патологічної фрагментації.
Ви можете розробити розподільники, щоб гарантувати, що не буде фрагментації (наприклад, шляхом виділення блоків лише одного розміру), але це створює суттєві обмеження для абонента і, можливо, збільшує обсяг пам'яті, необхідної через марнотратство. І той, хто телефонує, все одно повинен довести, що немає витоків, і що потрібна насичена верхня межа загальної пам'яті, незалежно від послідовності входів. Це навантаження настільки велике, що насправді спростити розробку системи таким чином, щоб вона не використовувала динамічне розподіл пам'яті.