【问题标题】:What happens if I call GlobalLock(), then fail to call GlobalUnlock()?如果我调用 GlobalLock(),然后调用 GlobalUnlock() 失败,会发生什么?
【发布时间】:2011-01-10 18:39:03
【问题描述】:

在 Win32 中,为了将数据粘贴到剪贴板中,我必须调用 GlobalAlloc(),然后调用 GlobalLock() 来获取指针,然后复制数据,然后调用 GlobalUnlock()SetClipboardData()

如果代码在 C++ 中,则在调用 GlobalLock()GlobalUnlock() 之间可能会引发异常,如果我不处理此问题,GlobalUnlock() 将不会被调用。

这是个问题吗?如果我打电话给GlobalLock() 并且出于某种原因跳过配对GlobalUnlock() 电话会发生什么?

【问题讨论】:

    标签: windows winapi visual-c++ memory-management


    【解决方案1】:

    问题不仅在于您是否致电GlobalUnlock()。您必须致电GlobalUnlock()GlobalFree()。必须调用两者才能释放您分配的内存:

    HGLOBAL hdl = NULL;
    void *ptr = NULL
    
      try {
        hdl = GlobalAlloc();
        ptr = GlobalLock(hdl);
    
        // etc...
        GlobalUnlock(hdl);
        ptr = NULL;
        SetClipboardData(..., hdl );
      }
      catch (...) {
        if(ptr)
            GlobalUnlock(hdl);
        if(hdl)
            GlobalFree(hdl);
        throw;
      }
    

    泄漏将是整个应用程序。当您退出 Windows 应用程序时,所有分配的私有内存都会自动释放

    【讨论】:

    • 不,如果将数据粘贴到剪贴板,则不应调用 GlobalFree() - 所有权已传递给剪贴板,稍后它将释放内存。
    • 是的,如果成功调用 SetClipboardData,您是对的。但否则,您必须同时调用两者。帖子已相应修改。
    【解决方案2】:

    关于GlobalLock(),比你想知道的更多(真的),由 Raymond Chen 提供:

    我正在标记这个社区 wiki,因为我实际上不知道这些文章是否回答了您的问题。但它们可能值得一读,至少略读一下。

    但是,在遇到异常时处理 GlobalUnlock() 问题的一种方法是使用 RAII 类来管理 GlobalLock()/GlobalUnlock() 调用。

    【讨论】:

    • 所有链接失效:-(
    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 2011-04-02
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    相关资源
    最近更新 更多