c++ - UIAutomation FindAll 泄漏内存

标签 c++ c memory-leaks ui-automation

即使调用了 array->Release,UIAutomation FindAll 函数也会泄漏我系统上的内存。请参阅下面示例程序中的“内存泄漏”。我已经对堆栈溢出进行了一些搜索,我看到了一些关于内存垃圾收集需要大约 3 分钟才能开始工作的评论,但我看到的是内存泄漏。请注意,下面的程序没有 malloc 或 new。 我正在使用带有 Service Pack 1 的 Windows 7。cl 版本是: Microsoft (R) 32 位 C/C++ 优化编译器版本 16.00.40219.01 for 80x86。

/* Program to demonstrate that IUIAutomation function FindAll leaks memory.
 * Build with: cl uia_memleak.cpp user32.lib ole32.lib oleaut32.lib 
 */

#include <windows.h>
#include <stdio.h>         /* for fprintf */
#include <assert.h>        /* for assert */
#include <UIAutomation.h>
#include <oleauto.h>


/* Forward declarations */
void loop_get_buttons(IUIAutomation * pui, HWND hwnd, int iterations);
int get_buttons(IUIAutomation * pui, HWND hwnd);
BOOL button_appender(IUIAutomation * pui, IUIAutomationElement * root);
BOOL button_condition_appender(IUIAutomation * pui, IUIAutomationElement * root, IUIAutomationCondition * condition);


int
main(int argc, char *argv[])
{
    int i;
    HRESULT hr;
    IUIAutomation *pui;

    CoInitialize(NULL);

    hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void **)&pui);
    assert(hr == S_OK);

    fprintf(stdout,
        "Open the Task Manager to observe the memory consumed by this program.  Press Enter and then open and select the calc program. You should see the Memory column increasing slowly.  This program will complete in under a minute.\n");
    getchar();

    for (i = 0; i < 100; i++) {
        HWND hwnd;
        hwnd = GetTopWindow(NULL);
        loop_get_buttons(pui, hwnd, 500);
    }

    fprintf(stdout, "Press Enter to quit.\n");
    getchar();
    CoUninitialize();
    return 0;
}


void
loop_get_buttons(IUIAutomation * pui, HWND hwnd, int iterations)
{
    int i;
    for (i = 0; i < iterations; i++) {
        get_buttons(pui, hwnd);
    }
}


int
get_buttons(IUIAutomation * pui, HWND hwnd)
{
    HRESULT hr;
    IUIAutomationElement *root = NULL;

    hr = pui->ElementFromHandle(hwnd, &root);
    assert(hr == S_OK);
    button_appender(pui, root);
    root->Release();
    return 0;
}


BOOL
button_appender(IUIAutomation * pui, IUIAutomationElement * root)
{
    /* Returns FALSE on success, TRUE on error. */
    HRESULT hr;
    VARIANT varProp;
    IUIAutomationCondition *condition;

    assert(root != NULL);

    varProp.vt = VT_I4;
    varProp.lVal = UIA_ButtonControlTypeId;
    hr = pui->CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, &condition);
    assert(hr == S_OK && condition != NULL);

    button_condition_appender(pui, root, condition);
    condition->Release();
    VariantClear(&varProp);
    return FALSE;
}


BOOL
button_condition_appender(IUIAutomation * pui, IUIAutomationElement * root,
              IUIAutomationCondition * condition)
{
    /* Returns FALSE on success, TRUE on error. */
    HRESULT hr;
    IUIAutomationElementArray *array = NULL;

    assert(root);

    hr = root->FindAll(TreeScope_Descendants, condition, &array);    /* memory leak */
    assert(hr == S_OK);
    if (array)
        array->Release();
    return FALSE;
}

最佳答案

以下答案是一个假设:

  • 释放 array->Release(); 是不够的,您必须分别释放数组中包含的每个元素。

findAll 方法的结果是通过输出参数 array 返回的 IUIAutomationElementArrayarray 包含多个 IUIAutomationElement 实例。 所有这些实例都必须被释放。

附言: 我找到了这篇文章,因为我想知道是否有必要发布每个元素。现在因为你的帖子,我认为它是。

关于c++ - UIAutomation FindAll 泄漏内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40875385/

相关文章:

C++ 如何创建嵌套类来转发你的方法?

c++ - OpenFrameworks,带有 OpenCV,VS2013 设置

c - 允许 llvm/clang 查看枚举标签的文本?

ios - UIBezierPath bezierPathWithRect 内存泄漏

c++ - 专门化 std::decay 有意义吗?

c++ - 错误 C2059 : syntax error: 'constant' from struct member declarations

c - 在 Linux 中获取自 1984 年 1 月 1 日午夜以来的绝对时间

c - 如何用C语言求解单变量线性方程

python - 从分配的数组在 C 中创建一个 numpy 数组会导致内存泄漏

绘制图表时 JavaFX WeakReference 内存泄漏