你知道是否有办法让 malloc 恢复其初始状态,就好像程序刚刚开始一样?
原因:我正在使用 nintendods devkitpro 开发一个嵌入式应用程序,我希望能够在出现软件故障时改进调试支持。我已经可以捕获大多数错误,例如返回控制台菜单,但是当捕获 std::bad_alloc 时这无法正常工作。
我怀疑我用于“软重启”的代码在某些我无法控制的时候涉及 malloc() 本身,所以我想“忘记有关正在运行的应用程序的所有内容并重新开始”。
你知道是否有办法让 malloc 恢复其初始状态,就好像程序刚刚开始一样?
原因:我正在使用 nintendods devkitpro 开发一个嵌入式应用程序,我希望能够在出现软件故障时改进调试支持。我已经可以捕获大多数错误,例如返回控制台菜单,但是当捕获 std::bad_alloc 时这无法正常工作。
我怀疑我用于“软重启”的代码在某些我无法控制的时候涉及 malloc() 本身,所以我想“忘记有关正在运行的应用程序的所有内容并重新开始”。
没有办法做到这一点可移植,尽管可以想象 C++ 的嵌入式实现可能会将其作为扩展提供。相反,您应该考虑编写自己的分配系统、使用内存池或使用现有库。
只有当我做了类似的事情时,我们使用了自己的分配器,它会保留对每个分配块的引用。如果我们想回滚,我们将释放所有分配的块并执行 longjmp 以重新启动程序。
在全局位置释放一点内存,例如
int* not_used = new i[1024];
然后,当您获得 a 时std::bad_alloc
,删除 not_used 并转到您的错误控制台。这个想法是给你的崩溃处理程序足够的空间来做你需要的事情。您必须调整保留了多少内存,以便您的控制台也不会收到内存不足错误。
如果您很聪明,实际上可以使用 not_used 。但是你必须小心,任何使用内存的东西都可能被删除,恕不另行通知。
重新开始的唯一方法是从存储中重新加载应用程序。DS 将所有内容加载到 RAM 中,这意味着数据部分已就地修改。
除了后进先出的顺序之外,您是否需要释放内存?如果没有,我建议您定义一个数组以使用所有可用内存(您可能必须调整链接器文件来执行此操作),然后初始化指向该数组开头的指针。然后编写自己的 malloc() 函数:
char *allocation_ptr = big_array; 无效 *malloc(size_t n) { void *temp = (void*)allocation_ptr; if (allocation_ptr > END_OF_ALLOCATION_AREA - n) 返回0; 分配_ptr += n; 返回温度; } void free_all_after(void *ptr) { 如果(指针) 分配_ptr = (char*)ptr; }
在这个实现中,free_all_after() 将释放指定的指针以及在它之后分配的所有内容。请注意,与 malloc() 的其他实现不同,此实现的开销为零。LIFO 分配非常有限,但对于许多嵌入式系统来说,这完全足够了。
我想如果没有其他东西在运行,您可以将 API 在 Nintendo 上提供的整个内存块写入零?但除此之外,只需跟踪您的分配。
实际上,如果您创建一个CatchAndRelease
类来保留对每个分配的内存块的引用,那么您可以在需要的时间返回并清除它们。
否则,您可能需要编写自己的内存池,如 Neil 所述。
当 new 失败并且无法分配请求的内存时,会发生 std::bad_alloc。这通常会在堆内存不足并因此无法满足请求时发生。因此,您将无法在清理过程中可靠地分配任何新内存。
这意味着您可能不会为清理分配新内存。成功清理的唯一希望是确保在实际需要之前为清理代码预先分配内存。
仍然可以使用 inplace new 运算符将对象更新到此清理内存中(即您提供内存地址的新对象)