【问题标题】:Pointer Ownership in the Win32 APIWin32 API 中的指针所有权
【发布时间】:2021-10-02 21:32:35
【问题描述】:

我试图了解 Win32 API 如何处理指针所有权。

我现在正在查看的具体示例是指向我传递给 API 并从 API 获取的字符串的指针的所有权。

SetWindowText 函数为例。它需要一个LPCSTR,一个指向空终止宽字符串的指针。

另一个例子是RegisterClass 函数和WNDCLASS 结构。 RegisterClass 函数采用指向 WNDCLASS 结构的指针,WNDCLASS 结构再次包含指向类名的 LPCSTR

API 是否拥有该内存的所有权,还是我需要处理释放它?

在我看来,它不太可能获得所有权,但我对 C/C++ 约定的了解还不足以肯定地说,而且我找不到任何有关 API 所有权约定的文档。

【问题讨论】:

  • Windows“Win32”API 不太关心 C 或 C++ 约定或其他编程语言的约定。这真的是一件好事,如果你看一下 Linux,两者纠缠在一起导致不幸的依赖关系。 malloc 是 C; HeapAlloc 是 Windows。

标签: c++ c windows pointers winapi


【解决方案1】:

API 是否拥有该内存的所有权,还是我需要处理释放它?

Win32 API 中没有这种自动内存管理。如果您在程序中分配一些数据并将这些数据提供给Win32 API 函数,您将不得不在您的程序中free

C 中的API 通常是这样设计的,因为其他层无法确定指针是否在程序的其他地方使用。如果手动内存管理让您感到厌烦,您可以搜索garbage collectors,它会自动为您管理内存,在性能方面稍作权衡。

【讨论】:

  • GdiPlus 使事情变得有些复杂。在某些情况下,它会在加载图像文件时分配一些内存,除非我弄错了,您将 需要稍后管理它的清理工作。长期以来,它一直是泄漏源。
  • API in C are usually designed like that, because there is no way for the other layers to determine if the pointers are used somewhere else in the program. 这并不是普遍正确的,因为“如果你给我一个指针,我现在拥有该内存并将处理清理,你最好不要再使用它了”的传递约定是API 假设它拥有内存所有权的方式。正如我所说,这是极不可能的,但我宁愿不被这样的脚枪绊倒,正如@enhzflep 指出的那样,规则的例外情况会发生。
  • 这是正确的,但我阅读了很多 C 代码,根据我的经验,allocation 函数大部分时间都附加到 free 函数。所以分配内存的层也负责释放它。
  • @ErikSchulze 指向某个内存的指针不包含足够的信息来让任何人释放它,而且通常可能还不够。分配内存的方法与您要求的人一样多,任何分歧=崩溃。所以这行不通。需要清理内存的 API 可以: 1. 提供内存开始(通过向用户公开的分配函数),或 2. 请求三个指针:内存指针、不透明指针和释放函数指针.解除分配器将传递以前的指针并执行解除分配工作。
  • C++ 被垃圾回收,只是everybody thinks about garbage collection the wrong way。无论如何,事情并没有这么简单。 Windows API 中有一些接口可以转移所有权(例如,如果需要,FormatMessage)。 COM 是另一个经常传递所有权的领域(例如IEnumString::Next)。
【解决方案2】:

一般答案是:阅读相关函数的文档。如果它没有说明任何关于取得所有权的内容,那么最好打赌它不取得所有权并且您需要处理内存。

虽然我在 Windows API 级别上做了很多重要的工作已经有一段时间了,但我记得偶尔会遇到记录它们首先需要通过特定方法分配内存的函数 - 因为这是唯一的方法知道如何正确释放它。

这就引出了第二种推理方式。想象一下你是这个函数的实现者。如果你只是得到一个没有其他信息的原始指针,你能知道如何释放它指向的内存吗?那块内存是用new 分配的吗? malloc?其他一些 API 调用?或者它在堆栈上? C / C ++ / Windows API 级别没有任何工具来确定如何仅通过指针来分配内存。因此,如果不需要,大多数功能都不会处理这种麻烦。少数有充分理由的人将不得不遵循记录他们的需求的路线。

【讨论】:

    猜你喜欢
    • 2012-07-07
    • 2011-07-28
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多