Вопрос

Знаете ли вы, есть ли способ вернуть malloc в исходное состояние, как будто программа только запускается?

причина :Я разрабатываю встроенное приложение с помощью nintendos devkitpro и хотел бы иметь возможность улучшить поддержку отладки в случае сбоев программного обеспечения.Я уже могу уловить большинство ошибок и, например.вернитесь в меню консоли, но это не работает при перехвате std::bad_alloc.

Я подозреваю, что код, который я использую для «мягкой перезагрузки», включает саму функцию malloc() в какой-то момент, который я не могу контролировать, поэтому я бы хотел «забыть все о работающем приложении и начать все сначала».

Это было полезно?

Решение

Единственный способ начать все сначала — перезагрузить приложение из хранилища.DS загружает все в оперативную память, а это означает, что раздел данных изменяется на месте.

Другие советы

Невозможно сделать это переносимо, хотя, возможно, встроенная реализация C++ может предоставить это как расширение.Вместо этого вам следует подумать о написании собственной системы распределения, использовании пулов памяти или использовании существующей библиотеки.

Единственный раз, когда я делал что-то подобное, мы использовали собственный распределитель, который сохранял ссылку на каждый выделенный блок.Если бы мы хотели выполнить откат, мы бы освободили все выделенные блоки и выполнили бы команду longjmp, чтобы перезапустить программу.

Выделите немного памяти в глобальном месте, например.

int* not_used = new i[1024];

Затем, когда вы получите std::bad_alloc, удалите not_used и перейдите к консоли ошибок.Идея состоит в том, чтобы предоставить вашему обработчику сбоев достаточно места, чтобы он мог делать то, что вам нужно.Вам придется настроить объем зарезервированной памяти, чтобы ваша консоль также не получала ошибок нехватки памяти.

Если вы умны, not_used действительно может быть использован.Но нужно быть осторожным, чтобы все, что использовало память, могло быть удалено без предупреждения.

Полагаю, если больше ничего не работает, вы могли бы обнулить весь блок памяти, который API предоставляет на Nintendo?Но в остальном просто следите за своими выделениями.

Фактически, если вы создадите CatchAndRelease чтобы хранить ссылку на каждый выделенный блок памяти, в нужный момент вы можете вернуться и очистить их.

В противном случае вам может потребоваться написать собственный пул памяти, как упоминал Нил.

Вам когда-нибудь приходилось освобождать память в порядке, отличном от «последним пришел — первым ушел»?Если нет, я бы предложил вам определить массив, который будет использовать всю доступную память (для этого вам, вероятно, придется настроить файлы компоновщика), а затем инициализировать указатель на начало этого массива.Затем напишите свою собственную функцию malloc():

char *allocation_ptr = big_array;

void *malloc(size_t n)
{
  void *temp = (void*)allocation_ptr;
  if (allocation_ptr > END_OF_ALLOCATION_AREA - n)
    return 0;
  allocation_ptr += n;
  return temp;
}

void free_all_after(void *ptr)
{
  if (ptr)
    allocation_ptr = (char*)ptr;
}

В этой реализации free_all_after() освободит указанный указатель. и все, что выделено после него.Обратите внимание, что в отличие от других реализаций malloc(), здесь есть нуль накладные расходы.Распределение LIFO очень ограничено, но для многих встроенных систем оно будет вполне достаточным.

std::bad_alloc возникает, когда new завершается сбоем и не может выделить запрошенную память.Обычно это происходит, когда в куче заканчивается память, и поэтому запрос не может быть обработан.По этой причине вы не сможете надежно выделить новую память при очистке.

Это означает, что вы не можете выделить новую память для очистки.Ваша единственная надежда на успешную очистку — убедиться, что память для кода очистки предварительно выделена задолго до того, как она вам действительно понадобится.

Объекты по-прежнему могут быть добавлены в эту очищаемую память с помощью нового оператора inplace (т. е. нового, когда вы указываете адрес памяти).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top