Mat a =(Mat_(3,3)<<<<< 1,0,0,0,1,0,0,0,1);
cv :: Mat b = a.row(1);
cv::Mat
有一个名为data
的字段,它是一个指向Mat的实际内存的指针。
我知道这是浅层副本,不会分配新内存来存储a.row(1)
b
中的元素。
a
和b
将共享同一段记忆
data
的{{1}}字段与b
的{{1}}字段相同。
我的问题是:
如果a
的{{1}}字段与data
的{{1}}字段相同,那么data
和b
之间有什么区别?
他们的a
字段相同,但其他功能data
和a
不同!!
他们怎么知道这个?
答案 0 :(得分:1)
我的假设是错的!
虽然没有分配新内存,但data
和a
的{{1}}字段不同!
以下是b
中标题的摘要代码,其中mat.hpp
的定义如下:
cv::Mat
当您进行浅拷贝时,只会复制指针class CV_EXPORTS Mat
{
public:
// ... a lot of methods ...
...
/*! includes several bit-fields:
- the magic signature
- continuity flag
- depth
- number of channels
*/
int flags;
//! the array dimensionality, >= 2
int dims;
//! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions
int rows, cols;
uchar* data;
//! pointer to the reference counter;
// when array points to user-allocated data, the pointer is NULL
int* refcount;
// other members
...
};
(而不是data
指向的东西)。
不会分配新记忆
比方说,我们有data
名为cv::Mat
。
cv :: Mat b = a;
a
&n; b
字段与data
字段相同。
不会为a
分配新的内存。
但是下面的代码呢?
cv :: Mat b = a.col(1);
这里是b
的代码段,其中包含cv :: Mat函数的实现:
matrix.cpp
Mat::Mat(const Mat& m, const Range* ranges)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
{
int i, d = m.dims;
CV_Assert(ranges);
for( i = 0; i < d; i++ )
{
Range r = ranges[i];
CV_Assert( r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i]) );
}
*this = m;
for( i = 0; i < d; i++ )
{
Range r = ranges[i];
if( r != Range::all() && r != Range(0, size.p[i]))
{
size.p[i] = r.end - r.start;
data += r.start*step.p[i];
flags |= SUBMATRIX_FLAG;
}
}
updateContinuityFlag(*this);
}
将返回一个新的cv::Mat::col()
,它需要调用一个构造函数
上面的构造函数用于构建cv::Mat
,其中包含另一个cv::Mat
引用和cv::Mat
。
请注意,cv::Range
字段不是data
的{{1}}字段的副本(data
是传递给构造函数的参数){{1} }。
所以,对于我的问题..
m
和m
的{{1}}字段不同!