使用 `new` 调用默认参数会导致内存泄漏吗?

Would calling the default parameter with `new` cause memory leak?

我正在尝试编写一个函数,使 return 成为检测到的最大对象的中心点。这里没问题。问题是我还想 return 来自参数的前景掩码,如果用户想使用它的话。

为了处理这种情况,我的解决方案如下:

cv::Point detect(const cv::Mat &img, cv::Mat &mask = *new cv::Mat());

如果指定了mask参数,则可以在main中使用。 RAII 在其他情况下是否有效,或者会不会有内存泄漏?

注意:我知道我可以将函数重载 2 行,但我想知道是否可以通过使用默认参数而不是使用指针(输入类型是严格的)。

另注:如果能用cv::noArray()或类似的功能就完全没问题

用法示例:

char ch = 0;
while (ch != 27) // ESC is pressed
{
    cap >> img;
    if (img.empty())
        break;
    cv::Mat mask;
    cv::Point pt = detect(img, mask);
    // or pt = detect(img);
    cv::imshow("original", img);
    cv::imshow("foreground", mask);
    ch = cv::waitKey(1);
}

是的,这会导致内存泄漏。您可能会考虑使用元组 return value:

std::tuple<cv::Point, cv::Mat> detect(const cv::Mat &img);

或使mask成为指针:

cv::Point detect(const cv::Mat &img, cv::Mat *mask = nullptr);

您也可以尝试使用演员表保持相同的签名。这很丑陋,但它可能有效:

cv::Point detect(const cv::Mat &img, cv::Mat &mask = const_cast<cv::Mat&>(static_cast<cv::Mat const&>(cv::Mat())));

丑陋,但没有内存泄漏:

cv::Point detect(const cv::Mat &img, cv::Mat &mask = *std::make_unique<cv::Mat>());

如果用户没有提供掩码,则会创建一个。 detect 会将掩码写回,然后立即销毁。使用重载会更有效率,因为它可以跳过不必要的更新。

或者,使用 cv::Mat* mask = nullptr。我不知道“(输入类型是严格的)”是什么意思。但对于有经验的 C++ 程序员来说,cv::Mat* mask = nullptr 模式很明确:可选输出参数,不暗示所有权转移。