向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, ¶ms.kSize, 100, onKSize, ¶ms); Refresh(¶ms); imshow(wndOriginal, original); waitKey(); return 0; }
内容的提问来源于stack exchange,提问作者Display Name
相关产品推荐
相关产品推荐

