You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows平台Qt 5.15.18中QAudioDeviceInfo疑似存在内存泄漏

Qt 5.15.18 Windows平台QAudioDeviceInfo::availableDevices()内存泄漏问题

问题概述

在Windows平台使用Qt 5.15.18版本时,调用QAudioDeviceInfo::availableDevices()存在持续内存泄漏问题(暂未测试其他平台)。

背景

需要实现实时检测Windows上特定音频设备是否存在的功能,因此周期性调用QAudioDeviceInfo::availableDevices()列出音频输入设备,但发现进程内存占用持续增长,疑似内存泄漏。

最小复现示例

#include <QApplication>
#include <QAudioDeviceInfo>
#include <QDebug>
#include <QPushButton>
#include <QTimer>
#include <QVBoxLayout>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget *w = new QWidget();
    w->resize(400, 300);
    w->show();

    QTimer *timer = new QTimer(w);
    QObject::connect(timer, &QTimer::timeout, w, [w]() {
        qDebug() << "Timer timeout";
        // 获取可用音频输入设备列表
        QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
        // 遍历设备并打印名称
        for (const QAudioDeviceInfo &device : devices)
        {
            qDebug() << "Device Name:" << device.deviceName();
        }
    });
    // 每100ms触发一次设备检测
    timer->start(100);

    int ret = app.exec();

    delete w;

    return ret;
}

观测到的行为

  • 在Windows上运行该代码时,进程内存占用(可通过任务管理器/资源监视器查看)随时间持续增加;
  • 尽管QList<QAudioDeviceInfo>是栈分配变量(应在lambda回调结束时销毁),但内存未被释放。

使用Visual Leak Detector (VLD)验证

通过Windows/MSVC广泛使用的内存泄漏检测工具VLD确认了该问题:

  • 重复调用availableDevices()时,VLD报告内存泄漏;
  • 移除该调用后无泄漏报告,确认泄漏源于Qt的QAudioDeviceInfo实现。

已排查内容

  • 预期栈分配的devices列表及QAudioDeviceInfo元素会在每次定时器回调后正确释放;
  • 未找到Qt 5.15.18版本关于该特定内存泄漏的相关Bug报告;
  • 该问题在多台Windows机器上均可稳定复现。

问题咨询

  1. Qt 5.15.18 Windows版本中QAudioDeviceInfo::availableDevices()的内存泄漏是否为已知问题?
  2. 我的代码是否存在内存管理不当等可能导致泄漏的问题?
  3. 有无可安全获取音频设备信息且无内存泄漏的替代方案?

VLD报告

---------- Block 182 at 0x0000000039725760: 78 bytes ----------
  Leak Hash: 0x68333E06, Count: 1, Total 78 bytes
  Call Stack (TID 31932):
    ntdll.dll!RtlAllocateHeap()
    MMDevAPI.DLL!0x00007FF99F45ED72()
    MMDevAPI.DLL!0x00007FF99F452FE2()
    wdmaud.drv!0x00007FF9327F4E6C()
    wdmaud.drv!0x00007FF9327F3298()
    wdmaud.drv!0x00007FF9327F7610()
    winmmbase.dll!0x00007FF952AE65DD()
    winmmbase.dll!0x00007FF952AEFB7F()
    qtaudio_windowsd.dll!0x00007FF8F5C840E8()
    qtaudio_windowsd.dll!0x00007FF8F5C83E68()
    qtaudio_windowsd.dll!0x00007FF8F5C83BDD()
    D:\B\Q\qtmultimedia\src\multimedia\audio\qaudiodevicefactory.cpp (204): Qt5Multimediad.dll!QAudioDeviceFactory::audioDeviceInfo() + 0x27 bytes
    D:\B\Q\qtmultimedia\src\multimedia\audio\qaudiodeviceinfo.cpp (68): Qt5Multimediad.dll!QAudioDeviceInfoPrivate::QAudioDeviceInfoPrivate() + 0x23 bytes
    D:\B\Q\qtmultimedia\src\multimedia\audio\qaudiodeviceinfo.cpp (443): Qt5Multimediad.dll!QAudioDeviceInfo::QAudioDeviceInfo() + 0x3A bytes
    D:\B\Q\qtmultimedia\src\multimedia\audio\qaudiodevicefactory.cpp (135): Qt5Multimediad.dll!QAudioDeviceFactory::availableDevices() + 0x22 bytes
    D:\B\Q\qtmultimedia\src\multimedia\audio\qaudiodeviceinfo.cpp (435): Qt5Multimediad.dll!QAudioDeviceInfo::availableDevices() + 0xE bytes
    D:\Home\Desktop\mm\src\main.cpp (23): app.exe!<lambda_972f05a238b8c048bbd3e638a6c9cd17>::operator()() + 0xD bytes
    D:\Qt\Qt5.15.18-msvc2022_64\include\QtCore\qobjectdefs_impl.h (146): app.exe!QtPrivate::FunctorCall<QtPrivate::IndexesList<>,QtPrivate::List<>,void,<lambda_972f05a238b8c048bbd3e638a6c9cd17> >::call() + 0xA bytes
    D:\Qt\Qt5.15.18-msvc2022_64\include\QtCore\qobjectdefs_impl.h (256): app.exe!QtPrivate::Functor<<lambda_972f05a238b8c048bbd3e638a6c9cd17>,0>::call<QtPrivate::List<>,void>() + 0xF bytes
    D:\Qt\Qt5.15.18-msvc2022_64\include\QtCore\qobjectdefs_impl.h (443): app.exe!QtPrivate::QFunctorSlotObject<<lambda_972f05a238b8c048bbd3e638a6c9cd17>,0,QtPrivate::List<>,void>::impl() + 0x1B bytes
    D:\B\Q\qtbase\src\corelib\kernel\qobjectdefs_impl.h (398): Qt5Cored.dll!QtPrivate::QSlotObjectBase::call() + 0x42 bytes
    D:\B\Q\qtbase\src\corelib\kernel\qobject.cpp (3928): Qt5Cored.dll!doActivate<0>() + 0x2F bytes
    D:\B\Q\qtbase\src\corelib\kernel\qobject.cpp (3988): Qt5Cored.dll!QMetaObject::activate() + 0x13 bytes
    D:\B\Q\build-msvc\qtbase\src\corelib\.moc\debug\moc_qtimer.cpp (205): Qt5Cored.dll!QTimer::timeout() + 0x19 bytes
    D:\B\Q\qtbase\src\corelib\kernel\qtimer.cpp (259): Qt5Cored.dll!QTimer::timerEvent() + 0xF bytes
    D:\B\Q\qtbase\src\corelib\kernel\qobject.cpp (1324): Qt5Cored.dll!QObject::event() + 0x2E bytes
    D:\B\Q\qtbase\src\widgets\kernel\qapplication.cpp (3640): Qt5Widgetsd.dll!QApplicationPrivate::notify_helper() + 0x1F bytes
    D:\B\Q\qtbase\src\widgets\kernel\qapplication.cpp (2980): Qt5Widgetsd.dll!QApplication::notify() + 0x1D bytes
    D:\B\Q\qtbase\src\corelib\kernel\qcoreapplication.cpp (1064): Qt5Cored.dll!QCoreApplication::notifyInternal2() + 0x2E bytes
    D:\B\Q\qtbase\src\corelib\kernel\qcoreapplication.cpp (1463): Qt5Cored.dll!QCoreApplication::sendEvent()
    D:\B\Q\qtbase\src\corelib\kernel\qeventdispatcher_win.cpp (432): Qt5Cored.dll!QEventDispatcherWin32Private::sendTimerEvent() + 0x13 bytes
    D:\B\Q\qtbase\src\corelib\kernel\qeventdispatcher_win.cpp (256): Qt5Cored.dll!qt_internal_proc() + 0x11 bytes
    USER32.dll!CallWindowProcW() + 0x6A6 bytes
    USER32.dll!IsWindowUnicode() + 0x3CD bytes
    D:\B\Q\qtbase\src\corelib\kernel\qeventdispatcher_win.cpp (597): Qt5Cored.dll!QEventDispatcherWin32::processEvents() + 0xB bytes
    qwindowsd.dll!0x00007FF89FB00024()
    D:\B\Q\qtbase\src\corelib\kernel\qeventloop.cpp (143): Qt5Cored.dll!QEventLoop::processEvents()
    D:\B\Q\qtbase\src\corelib\kernel\qeventloop.cpp (235): Qt5Cored.dll!QEventLoop::exec() + 0x41 bytes
    D:\B\Q\qtbase\src\corelib\kernel\qcoreapplication.cpp (1375): Qt5Cored.dll!QCoreApplication::exec() + 0x22 bytes
    D:\B\Q\qtbase\src\gui\kernel\qguiapplication.cpp (1871): Qt5Guid.dll!QGuiApplication::exec()
    D:\B\Q\qtbase\src\widgets\kernel\qapplication.cpp (2833): Qt5Widgetsd.dll!QApplication::exec()
    D:\Home\Desktop\mm\src\main.cpp (31): app.exe!main() + 0x6 bytes
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (79): app.exe!invoke_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (288): app.exe!__scrt_common_main_seh() + 0x5 bytes
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): app.exe!__scrt_common_main()
    D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): app.exe!mainCRTStartup()
    KERNEL32.DLL!BaseThreadInitThunk() + 0x17 bytes
    ntdll.dll!RtlUserThreadStart() + 0x2C bytes
  Data:
    7B 00 32 00    38 00 66 00    62 00 62 00    35 00 34 00     {.2.8.f. b.b.5.4.
    31 00 2D 00    66 00 63 00    65 00 65 00    2D 00 34 00     1.-.f.c. e.e.-.4.
    30 00 62 00    36 00 2D 00    62 00 34 00    33 00 34 00     0.b.6.-. b.4.3.4.
    2D 00 32 00    64 00 31 00    66 00 38 00    30 00 38 00     -.2.d.1. f.8.0.8.
    36 00 62 00    64 00 65 00    34 00 7D 00    00 00           6.b.d.e. 4.}.....


Visual Leak Detector detected 37 memory leaks (2232 bytes).
Largest number used: 11387 bytes.
Total allocations: 50233 bytes.
Visual Leak Detector is now exiting.

内容的提问来源于stack exchange,提问作者Jim Weiss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 10:34:49