8

在“Inside the C++ Object Model”一书的 6.3 节中,临时对象(第 230 页):

实际结果取决于实现,具体取决于底层删除运算符在实际释放已寻址内存方面的积极程度。一些实现,虽然将内存标记为空闲,但实际上并没有以任何方式改变它。在内存被其他东西占用之前,它可以像没有被删除一样使用。虽然显然不是软件工程的典型方法,但这种在内存释放后访问内存的习惯用法并不少见。 事实上,许多 的实现都提供了一个特殊的调用来保证这种行为。malloc()malloc(0);

根据上述,malloc(0)似乎与访问已经被释放的内存(但其内容没有改变)有关。

我的问题是如何malloc(0)保证这种行为?

4

3 回答 3

2

编辑:我没有注意到“C++ 对象模型内部”是一个参考,而不仅仅是问题标题的一部分。

正如 Dietmar Kuhl 所说,它看起来像一个杂物,即使它出现在你的平台上,你也不应该依赖这样的扩展。

“大多数平台”确实包含某种malloc调试工具,以帮助程序员找到访问已传递给free. 这可能涉及不那么懒惰地执行内存管理或使用特殊字节模式覆盖。听起来该文本正在描述malloc(0)为禁用此类设施的一种手段。在 Mac OS XI 上回想一下,有一个环境变量(类似于MALLOC_DEBUG)可以控制它。该设施的功能和启用方式在平台之间会有很大差异。覆盖malloc(0)既不常见,也不是一个好的接口。

编辑:我在斯坦利·利普曼(Stanley Lippman)的《C++ 对象模型内部》中找到了它,1996 年。不是权威来源。整个页面似乎都致力于讨论标准和“准标准”平台实现之间的差异,尽管 1996 年也是在第一个标准完成之前。请注意,这是很久很久以前的计算机时代,除非您将特定的应用程序从死里复活,否则这些信息将完全无关紧要。Lippman 显然发布了一本关于 C++11 的新书,其中包括具有多线程支持的更新对象模型。(虽然我不知道他或那本书是否好。)

于 2012-12-25T06:24:27.430 回答
1

从引用看来,似乎有一些实现malloc()用作malloc(0)某种开关,以指示将来调用malloc()分配内存的方式free()(并且可能realloc(p, 0))在将分配内存标记为未使用时不会更改分配内存的内容。显然,这是一个符合标准的扩展,您最好不要依赖它。

于 2012-12-25T03:50:07.370 回答
0

从实际的角度来看malloc,甚至不能授予一些空间来真正分配。

了解如何malloc操作的最有效方法是将其视为对内核的请求,内核可以说“ok”或“no”,但如果内核说“ok”,您根本无法确定它是否真的为您分配内存,或者只是说“好的”让您开心。

这是一种关于内存页面的超额预订,例如,这是 linux 下的一个常见问题,通常 linux 内核对malloc请求是高度允许的,但即使您的malloc请求返回一个肯定的结果,您也可能会耗尽内存。

如果您想为“Linux memory overcommit”的主题搜索命名,并且您将大致了解mallocLinux 下的工作原理,类似的概念适用于其他平台,这意味着您永远不会从malloc和一切基本上都取决于内核。

于 2012-12-25T03:40:21.480 回答