UIAutomation FindAll泄漏内存

时间:2016-11-29 20:41:23

标签: 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;
}

1 个答案:

答案 0 :(得分:0)

以下答案是一个假设:

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

findAll方法的结果是通过外部参数IUIAutomationElementArray返回的arrayarray包含多个IUIAutomationElement实例。 所有这些实例都必须释放。

PS: 我找到了这篇文章,是因为我想知道是否需要释放每个元素。现在,由于您的帖子,我认为是这样。