From aed41fdabe3c5381395e2a7a8272c7519f3c289f Mon Sep 17 00:00:00 2001 From: Srujan rai Date: Wed, 10 Jun 2026 22:56:55 +0530 Subject: [PATCH] Merge pull request #28981 from Srujan-rai:fix/opengl-extensions-memory-leak core(opengl): fix memory leak in OpenCL extensions gathering #28981 ## Problem Fixes #28980 In `modules/core/src/opengl.cpp`, inside `initializeContextFromGL()`, a `char[]` buffer is allocated to query OpenCL device extensions: ```cpp extensions = new char[extensionSize]; status = clGetDeviceInfo(..., extensions, &extensionSize); if (status != CL_SUCCESS) continue; // leaks `extensions` ``` When `clGetDeviceInfo()` fails, `continue` skips the corresponding `delete[]` on the success path, causing the allocated buffer to leak. Additionally, the `catch (...)` block also bypasses cleanup, so any thrown exception leaks the buffer as well. ## Fix Replace the raw `char*` allocation with `std::unique_ptr`. This ensures the buffer is automatically released on all exit paths, including: - normal execution - early `continue` - exception handling paths ## Checklist - [x] I agree to contribute to the project under the Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on code under GPL or another license incompatible with OpenCV. - [x] The PR is proposed to the proper branch (`4.x`). - [x] There is a reference to the original bug report and related work, if applicable. - [x] Accuracy/performance tests and test data in `opencv_extra` are included, if applicable. - [x] The feature/change is documented and sample code can be built with the project CMake configuration, if applicable. --- modules/core/src/opengl.cpp | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/modules/core/src/opengl.cpp b/modules/core/src/opengl.cpp index 83be34f147..b7a85a61a4 100644 --- a/modules/core/src/opengl.cpp +++ b/modules/core/src/opengl.cpp @@ -1682,27 +1682,12 @@ Context& initializeContextFromGL() if(extensionSize > 0) { - char* extensions = nullptr; - - try { - extensions = new char[extensionSize]; - - status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize); - if (status != CL_SUCCESS) - continue; - } catch(...) { - CV_Error(cv::Error::OpenCLInitError, "OpenCL: Exception thrown during device extensions gathering"); - } - - std::string devString; - - if(extensions != nullptr) { - devString = extensions; - delete[] extensions; - } - else { - CV_Error(cv::Error::OpenCLInitError, "OpenCL: Unexpected error during device extensions gathering"); - } + std::string devString(extensionSize, '\0'); + status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, devString.size(), &devString[0], &extensionSize); + if (status != CL_SUCCESS) + continue; + if (extensionSize > 0 && devString.size() >= extensionSize) + devString.resize(extensionSize - 1); size_t oldPos = 0; size_t spacePos = devString.find(' ', oldPos); // extensions string is space delimited