1

I find the OpenCV memory management quite confusing. I read the documentation here http://opencv.itseez.com/modules/core/doc/intro.html#automatic-memory-management, but I really don't think it gives enough information to fully understand it.

For example consider the following snippet

Mat_<float> a,b,c;

a = b; // The header of b is copied into a and they share the data
b = c; // Now b refers to c and a != b
b = a + 1; // b still shares data with c and s.t. b = c;

Does it make any sense? Someone can explain the idea behind it?

2 Answers 2

5

You need to allocate memory separately from declaring matrices a, b & c

cv::Mat b(10, 10, CV8U_C1);    //this allocates 10 rows and 10 columns of 8 bit data to matrix b
cv::Mat a;    //This defines a matrix with an empty header.  You *cannot* yet assign data to it - trying to do so will give a segmentation fault
a = b;    //matrix a is now equal to matrix b.  The underlying data (a pointer to 10 x 10 uints) is shared by both so it is a shallow copy (and thus very efficient).  However modifying the data in martix a will now modify the data in matrix b
cv::Mat c(10, 10, CV8U_C1);
b = c;      //This will change matrix b to point to the newly allocated data in matrix c.  Matrix a now has the sole access to its data as matrix b no longer shares it.  Matrix b and c share the same data;
b = a + 1    //This statement makes no sense.  Even if it is valid you should never use it - it is completely unclear what it does
Sign up to request clarification or add additional context in comments.

1 Comment

Why b = a + 1 makes no sense? Pretty much every linalg library overloads operators so I guess that's pretty common. it's simply an element-wise addition. My question was: why b = a + 1; // b still shares data with c and s.t. b = c; b should not share the data with c anymore right? It should just point to the newly allocated matrix a + 1;
1

For a general understanding of the problem, you must read some theory about smart pointers http://en.wikipedia.org/wiki/Smart_pointer

many objects in OpenCV, including Mat are implemented as smart pointers.

5 Comments

I know but consider the call b = a + 1; First (a + 1) generates a new matrix Mat operator+(Mat,Scalar) then this new matrix is assigned to b. Thus shouldn't be b pointing to the new (a+1) matrix instead of copying the data into its pointed memory?
Mat object is so designed that it does not re-create memory when the new assigned object has the same size as before. So the result is kept in the old data space, which is actually the space shared by matrices c and b. If you assign a bigger matrix to b (b.create(10,10, CV_8UC1)), the old data pointer will be used only by c, and b will have its own space.
I see. Sounds really error prone they should just change it. Thanks
actually it's one of the best ideas of the OpenCV. Easy to use while extremely fast. When doing real-time image processing, alloc/dealloc can be deadly costly. And you can write very clean, safe code. You just have to become used to its style.
I mean shared pointers are good but either it's always shared or not. b = Mat(M,N) shouldn't have a different behavior depending on M,N (as you said if M*N = size(b) results will be stored in the old space otherwise new space will be allocated and all references to b will be broken.). When programs gets being it's difficult to predict run-time changing parameters...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.