【发布时间】:2017-02-18 09:53:00
【问题描述】:
我对以下案例有些困惑。我有以下 C++ 类,代表一个 RGB 像素:
class RgbColorVector
{
cv::Mat pM;
public:
RgbColorVector(unsigned int r,unsigned int g,unsigned int b)
{
pM = cv::Mat(3,1,CV_8UC1);
pM.at<unsigned char>(0,0) = r;
pM.at<unsigned char>(1,0) = g;
pM.at<unsigned char>(2,0) = b;
}
unsigned int getComponent(int c)
{
return (unsigned int)pM.at<unsigned char>(c,0);
}
这里我使用 OpenCV Mat 对象来保存一个 RGB 值。通常在这种情况下,我会使用 cv::Mat 指针并在构造函数中使用 new 运算符分配堆内存,然后在析构函数中使用 delete 释放它。在上面的例子中,我显式地调用了 cv::Mat 的构造函数。我的预期是,当 RgbColorVector 的构造函数退出时, cv::Mat 构造函数中分配的内存将被破坏。但显然情况并非如此:
void func()
{
RgbColorVector rgbVec(105,42,45);
int g = rgbVec.getComponent(1);
std::cout<<g<<std::endl;
}
int main(int argc, const char * argv[]) {
func();
return 0;
}
在这里,我得到输出 42。我知道“rgbVec”是一个本地(自动)变量,当“func”退出时,它的内容(类成员)将被销毁。但此外,我预计 getComponent() 调用将返回一个随机值,因为在 cv::Mat 构造函数调用中分配的任何内存都将在“rgbVec”的构造函数返回后被销毁。我在这里有点困惑,在这种情况下内存分配机制究竟是如何工作的? cv::Mat 对象不是在 RgbColorVector() 构造函数的栈上分配的吗?
【问题讨论】:
-
我不知道你会期待什么样的行为。您正在使用 cv::Mat 的复制构造函数 pM = cv::Mat(3,1,CV_8UC1);所以构造的对象在你的类成员变量中(如果类对象被销毁,它将被销毁),它位于 func() 的末尾。此外,如果您真的要访问已释放的内存,则不会返回“随机”值,而是返回内存中的值。如果内存仍然属于您的程序并且没有被覆盖,如果您不小心释放了内存,您甚至可能会观察到“正确”的值。
-
使用 Mat 存储单个像素值非常糟糕。你最好使用 Vec3b,或者只使用 3 个 uchars
标签: c++ opencv memory-management constructor