Если по умолчанию функции выделения памяти abort()
, а код GMP не может иметь дело с NULL
, то GMP, вероятно, вообще не подготовлен к тому, чтобы иметь дело с возможностью сбоев выделения памяти вообще.Если вы вернете заведомо неверный адрес, GMP, вероятно, попытается разыменовать его и быстро завершить работу, что так же плохо, как и вызов abort()
.Хуже того, даже потому, что трассировка стека не будет указывать на то, что действительно вызывает проблему.
Таким образом, если вы собираетесь вернуться вообще, вы должны вернуть действительный указатель,тот, который не используется ничем другим.
Теперь, один слегка злой вариант - использовать setjmp()
и longjmp()
для выхода из процедур GMP.Однако это оставит GMP в непредсказуемом состоянии - вы должны предположить, что после этого момента вы никогда не сможете снова вызвать процедуру GMP.Это также может привести к утечкам памяти ... но это, вероятно, наименьшая из ваших проблем на данный момент.
Другой вариант - иметь зарезервированный пул в системном malloc, то есть при запуске приложения:
emergencyMemory = malloc(bignumber);
Теперь, если malloc()
терпит неудачу, вы делаете free(emergencyMemory)
, и, надеюсь, у вас есть достаточно места для восстановления.Имейте в виду, что это дает вам лишь ограниченный запас - вы должны надеяться, что GMP вернется к вашему коду (и этот код проверит и увидит, что аварийный пул был использован), прежде чем вы действительно исчерпаете память.
Конечно, вы также можете использовать эти два метода в комбинации - сначала используйте зарезервированный пул и попробуйте восстановить, а в случае сбоя longjmp()
выведите сообщение об ошибке (если можете) и завершите работу.грациозно.