简体   繁体   English

UIAutomation FindAll泄漏内存

[英]UIAutomation FindAll leaks memory

The UIAutomation FindAll function leaks memory on my system even though array->Release is called. 即使调用了array-> Release,UIAutomation FindAll函数也会泄漏我系统上的内存。 See "memory leak" in the example program below. 请参阅下面的示例程序中的“内存泄漏”。 I've done some searching around on stack overflow, and I've seen some comments about memory garbage collection taking about 3 minutes start working, but what I see is a memory leak. 我已经做了一些关于堆栈溢出的搜索,我已经看到一些关于内存垃圾收集的评论大约花了3分钟开始工作,但我看到的是内存泄漏。 Note that the program below has no malloc or new. 请注意,下面的程序没有malloc或new。 I'm using Windows 7 with Service Pack 1. cl version is: Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86. 我正在使用Windows 7 Service Pack 1.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;
}

The following answer is an hypothesis: 以下答案是一个假设:

  • It is not sufficient to release the array->Release(); 释放array->Release();是不够的array->Release(); , but you'll have to release each element contained in the array separately. ,但你必须分别释放数组中包含的每个元素。

The result of the findAll method is an IUIAutomationElementArray returned through the out-parameter array . findAll方法的结果是通过out-parameter array返回的IUIAutomationElementArray array contains multiple IUIAutomationElement instances. array包含多个IUIAutomationElement实例。 All those instances have to be released. 所有这些实例都必须被释放。

PS: I found this post, because I was wondering whether the release of each element is necessary. PS:我找到了这篇文章,因为我想知道每个元素的发布是否必要。 Now because of your post I assume it is. 现在因为你的帖子我认为是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM