2014-01-08 2 views
6

Хотелось бы зарегистрировать и, возможно, предупредить пользователя о том, что в программе должно быть не хватает памяти, что позволяет им попытаться освободить некоторых (надеюсь). Хотя я могу предопределить необходимые объекты GUI, необходимые для отображения ситуации, я обеспокоен тем, что в этой ситуации могут быть невозможны более основные операции с использованием cstdio, такие как открытие или запись в файл.Запись ошибки «Без памяти» в файл, без памяти?

Мой вопрос:, если программа больше не может динамически выделять память вообще, возможно ли использовать cstdio? Существуют ли какие-либо специальные меры, которые мне потребуются, например, если файл предварительно открыт или не использовать буфер? Будут ли функции cstring функционировать? Любые другие возможные препятствия, чтобы знать об этом типе сценария?

(Предупреждение пользователю роскошь в этом случае основная цель состоит в том, чтобы зарегистрировать ошибку в файл, а затем попытаться спасти соответствующие данные с cstdio, то предупредить пользователя, в таком порядке)

+3

Когда вы получите эту ошибку, может быть слишком поздно, но у вас есть такая же ошибка, даже если вы не можете выделить достаточно ** непрерывное пространство **, так что другие операции могут работать, даже если один запрос распределения не смогли. Я предлагаю предупреждать пользователя (и записывать журнал), когда свободная память идет ** ниже порога ** (как часто эта проверка должна выполняться, зависит от вашего шаблона распределения). –

+0

Прямо сейчас, память не объединена заранее, ее просто хватают из ОС по мере необходимости. (Необходимо будет скоро это изменить). Способ распределения памяти, тем не менее, повторит попытку распределения после регистрации/предупреждения. Если после этого программа не попытается выделить больше памяти (и вызывает сбой), или сценарий не изменится, следует восстановить (надеюсь!) –

+8

Одним из способов, с помощью которого мы попытались решить эту проблему в некоторых из игр, над которыми я работал, было выделение буфера при регистрации нашего обработчика исключений, а затем, если бы произошло исключение, мы освободили бы буфер и, надеюсь, имели бы достаточно памяти, чтобы позволить обработчику выписывать необходимые ему данные. –

ответ

1

Короткий ответ на ваш вопрос «вероятно, нет» (см. этот ответ: https://stackoverflow.com/a/6743056/789491). Существуют версии с открытым исходным кодом snprintf(), которые не используют динамические распределения. Я бы использовал это и mmap (2) для записи в ваш файл.

Я угадываю причину, по которой вы хотите использовать cstdio, у вас уже есть какой-то причудливый код регистрации/сериализации, который использует cstdio. Учитывая это, я буду держать это решение на высоком уровне.

В этом случае в начале я бы выделил буфер, достаточно большой для хранения вашего сообщения об ошибке и данных восстановления (a la @ Retired-Ninja). Я бы сделал буфер размером не менее одной страницы (4096 байт в моей Linux-упаковке). Я также открыл файл журнала, в который я хочу записать, и файл mmap (2) с размером буфера, который я хочу.

В моем обработчике исключений из памяти я сначала освободил буфер (чтобы дать мне некоторую память для работы) и построил сообщение об ошибке в файле mmap'd, используя бесплатную версию snprintf без malloc. Я бы затем fsync файл (я не трассировал исходный код fsync, чтобы проверить, сколько или сколько памяти он выделяет, но он должен быть меньше, чем cstdio). Затем я закрою файл, сделаю все, что вы захотите (обработка графического интерфейса и т. Д.), И выйдите.

Когда моя программа завершается нормально, я просто удалю файл журнала, который я создал с помощью mmap.

Если объем данных, которые вы пытаетесь сохранить, является большим (например, большим, чем страница) и переменной, вы можете просто выделить буфер на одной странице и создать файл журнала по одной странице за раз. Или вы можете сделать что-то вроде этого https://stackoverflow.com/a/8704032/789491.

HTH.

--Jason

Смежные вопросы