【问题标题】:Is it possible to free memory using an offset pointer?是否可以使用偏移指针释放内存?
【发布时间】:2010-07-16 18:15:00
【问题描述】:

假设我在内存中有一个包含字符串"ABCDEFG" 的分配,但我只有一个指向'E' 的指针。在 win32 上,是否有可能释放该块,给定一个 块内的指针,但不是在开始处?任何分配方法都可以,但Heap* 函数将是阻力最小的路径。

如果不是本机解决方案,是否编写了任何提供此功能的自定义内存管理器?

编辑:这不是马虎的借口。我正在开发一个使用 100% 编译时元数据的自动内存管理系统。这个奇怪的要求似乎是让它工作的唯一障碍,即使这样,它也只需要基于数组的数据类型(可切片)。

【问题讨论】:

    标签: windows memory-management


    【解决方案1】:

    运行时库中的内存分配例程可以根据每个分配块的开头和结尾检查给定的内存地址。搜索完成后,从头释放块很容易。

    即使背后有聪明的算法,这也会在每次内存释放时引发某种搜索。为什么?只是为了支持那些愚蠢到无法跟踪它们分配的内存块的开头的错误程序?

    标准的 C 语言习惯在将分配的内存块视为数组时蓬勃发展。从 *alloc 返回的指针是一个指向数组开头的指针,该指针可以与下标一起使用来访问该数组的任何元素,下标从 0 开始。这已经工作了 40 年,我不能想一个合理的理由在此处引入更改。

    【讨论】:

    • +1 - “为什么?只是为了支持那些愚蠢到无法跟踪它们分配的内存块的开头的错误程序?”
    • 我愿意接受一些运行时惩罚......我怀疑它无论如何都可以很容易地最小化(想想:二进制搜索)。请记住,所有动态分配都是不确定的。仅仅因为 40 年来一直以同样的方式做某事并没有理由不进行创新,事实上我想说的恰恰相反。查看我的编辑。
    • 好吧,如果您正在编写内存管理系统,那么您就可以完美地解决这个问题。你会想要保持一个平衡的 b-tree 的起始地址块你分配的内存,当你想释放一块内存给一个指向它内部某个地方的指针时,你在树中搜索低于你的最高起始地址指针。除了整理树的工作外,这还可以解决您的问题。在分配的块数中,搜索时间将是 O(logN)。
    • 假设我在现有分配器之上分层,这实际上听起来很简单。有一个 +1 虽然我会坚持一个答案,以防有人知道为这种用途而构建的库。
    【解决方案2】:

    我想如果你知道 malloc() 保护块的样子,你可以编写一个函数,从你传递的指针开始备份,直到找到原始内存地址的“最佳猜测”,然后调用 @987654322 @。为什么不保留一份基本指针的副本?

    【讨论】:

    • 扫描回保护块将是一个坏主意,因为 (a) 顺序扫描的性能和 (b) 几乎不可能确定您在内存中找到的模式确实是一个保护块。我们可能同意跟踪块分配的起始地址是唯一明智的解决方案。
    【解决方案3】:

    如果你使用VirtualAlloc分配内存,你可以使用VirtualQuery来判断一个指针属于哪个块。获得基地址后,您可以将其传递给VirtualFree 以释放整个块。

    【讨论】:

    • 这看起来很棒,除了页面粒度分配。我的内存需求会像没有明天一样膨胀,也没有 32 位地址限制。
    猜你喜欢
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 2017-01-06
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多