使用 `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
模式很明确:可选输出参数,不暗示所有权转移。
我正在尝试编写一个函数,使 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
模式很明确:可选输出参数,不暗示所有权转移。