You need to enable JavaScript to run this app. 向createTrackbar传入new int(71)作为int*参数是否会内存泄漏?有无更优方案?
优惠活动
大模型
产品
解决方案
定价
更多

向createTrackbar传入new int(71)作为int*参数是否会内存泄漏?有无更优方案?

问题1:传入new int(71)会造成内存泄漏吗?

会。OpenCV的createTrackbar不会主动释放你传入的堆内存指针,程序退出后这块内存会被操作系统回收,但从程序设计规范来看属于明确的内存泄漏,不推荐这么写。


你提到的两种不可行/不合理方案原因

  • 不合理方案A:如果init是main函数内的局部变量,本身生命周期和main同步,指针不会悬空,问题在于你现有的全局Refresh函数无法访问main内的局部变量,如果你后续调整作用域会有悬空指针风险,且扩展性很差。
  • 不可行方案B:传入指针后立刻释放,后续createTrackbar内部操作、回调函数触发时访问的都是悬空指针,会直接引发程序崩溃。

合理解决方案

方案1:直接通过getTrackbarPos取值(最适合你当前场景)

你注释里已经写了这个思路,完全不需要额外维护int变量,也不需要传入指针给createTrackbar,滑块的值可以随时通过窗口+滑块名获取,直接删掉全局变量即可:

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

const string wndOriginal = "Original";
const string wndBlurred = "Blurred";
const string tbKSize = "KSize";
const string path = "../resources/test.png";

Mat original = imread(path);
Mat blurred;

void Refresh()
{
    // 直接从滑块取当前值,不需要维护外部变量
    int localKSize = getTrackbarPos(tbKSize, wndBlurred);
    // 加个边界判断避免传入非法值
    if (localKSize >= 1 && localKSize % 2 != 0)
        GaussianBlur(original, blurred, cv::Size(localKSize, localKSize), 3, 0);
    imshow(wndBlurred, blurred);
}

void onKSize(int, void *)
{
    Refresh();
}

int main()
{
    namedWindow(wndOriginal);
    namedWindow(wndBlurred);

    // 第三个参数传nullptr,不需要绑定外部变量
    createTrackbar(tbKSize, wndBlurred, nullptr, 100, onKSize);
    // 手动设置滑块初始值
    setTrackbarPos(tbKSize, wndBlurred, 71);

    Refresh();
    imshow(wndOriginal, original);

    waitKey();
    return 0;
}

方案2:封装参数结构体通过用户数据指针传递(适合多参数场景)

如果你有多个滑块需要维护参数,可以把所有参数封装到一个结构体里,通过createTrackbar的最后一个用户参数传递指针,既不需要全局变量,也不会有内存问题:

// 定义参数结构体,所有滑块参数都可以放这里
struct AppParams {
    int kSize = 71;
    // 可扩展其他参数:比如sigma、阈值之类的
};

const string wndOriginal = "Original";
const string wndBlurred = "Blurred";
const string tbKSize = "KSize";
const string path = "../resources/test.png";

Mat original = imread(path);
Mat blurred;

void Refresh(const AppParams* params)
{
    if (params->kSize >= 1 && params->kSize % 2 != 0)
        GaussianBlur(original, blurred, cv::Size(params->kSize, params->kSize), 3, 0);
    imshow(wndBlurred, blurred);
}

void onKSize(int currentVal, void* userData)
{
    AppParams* params = static_cast<AppParams*>(userData);
    params->kSize = currentVal;
    Refresh(params);
}

int main()
{
    AppParams params; // 局部变量,生命周期和main同步,无内存泄漏风险
    namedWindow(wndOriginal);
    namedWindow(wndBlurred);

    // 最后一个参数传入结构体指针,回调里可以拿到所有参数
    createTrackbar(tbKSize, wndBlurred, &params.kSize, 100, onKSize, &params);

    Refresh(&params);
    imshow(wndOriginal, original);

    waitKey();
    return 0;
}

内容的提问来源于stack exchange,提问作者Display Name

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 23:06:05