Quo*_*han 3 c algorithm memory-management out-of-memory data-structures
我正在用C实现一些复杂的数据结构,以支持各种操作。该数据结构使用许多其他动态结构(图形,AVL树,链接列表),所有内容都在使用动态内存。
当执行某些操作时,例如插入我的数据结构,显然我必须分配内存,有时会分配很多内存(因此结构会增长)。在执行某些操作的过程中,这可能导致内存不足(malloc()返回NULL)。现在,我不想终止程序,而是让操作的调用者知道该操作失败,并让调用者继续执行。
我的问题是,当操作由于内存分配失败而在执行过程中失败时,我想撤消自调用该操作以来所做的一切,撤消数据结构中的那些更改,就好像从未调用此操作(因此请在执行操作之前将数据结构还原为状态)。我需要这样做是因为即使操作失败,我也希望数据结构处于有效且可用的状态,因此我可以继续使用它。
由于数据结构相当先进,因此我正在寻找有关在调用操作之前将动态数据结构恢复为其状态的常规方法,提示和技巧。也许您有处理此类问题的经验,听说过此问题,或者可以建议一些有关此问题或相关源代码的书籍/文章。
编辑:一个简单的例子将从C ++设置为<>。根据STL文档,即使抛出异常,set :: insert也能很好地工作,因此即使set(可能是红黑树)的基础数据结构非常先进,它也可以以某种方式还原set :: insert执行期间所做的更改。 。
来自cplusplus.com的引用:“如果要插入单个元素,则在发生异常的情况下容器中不会有任何更改(强烈保证)。否则,保证容器以有效状态结束(基本保证)。”
处理此类情况的常用方法是,首先进行空运行并分配整个操作所需的内存。并且仅在所有分配成功后才进行更新。
当然,这可能并不总是可能的,因为您可能必须调用其他不具有“空运行”模式的操作,或者在实际执行该操作之前可能不会显示某些分配。在这种情况下,复制数据结构通常是最佳选择。同样,由于复制是只读操作,因此很容易中止和撤消操作。
用户可能希望避免重复和跟踪额外的数据结构或进行空运行的开销。因此,可以将此功能作为可选功能(可以使用#ifdef),使用户可以在反转操作还是终止整个程序之间进行选择。