Member variable u of cv::Mat is still NULL

OpenCV version 4.5.4

When a cv::Mat variable is created in a certain constructor, u, a member of cv::Mat, becomes NULL.
The following code is a simple example.

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::Mat a = cv::Mat::zeros(3, 3, CV_8UC3);
    cv::Mat b = cv::Mat(a.rows, a.cols, CV_8UC3, a.data);

    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << a.u << std::endl;
    std::cout << b.u << std::endl;
    return 0;
}

The results of this program are as follows.

[  0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0]
[  0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0]
00000203AC74C3A0
0000000000000000

Is this a constructor bug?
Also, is there any problem with u being NULL?

Thanks.

what is your interest in this member variable?
you have expectations of this member variable. what do you base these expectations on?

these are important questions, not rhetorical.

https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#a2742469fe595e1b9036f60d752d08461

you must reproduce any issues with the current release or git master. we will not debug anything that could have been fixed in the meantime. 4.5.4 is ancient.

I’m wondering if the reference counter works correctly when u is NULL.

I found this problem while debugging the Windows bitmap to cv::Mat conversion process.
Then I realized that u contains the cv::Mat reference counter.

In my current environment, it is difficult to try the latest version of OpenCV right away.
I will verify as soon as possible.

I have verified this with version 4.10.0 and it outputs similar results.

I also found that b->u is not NULL in the following code.

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::Mat a = cv::Mat::zeros(3, 3, CV_8UC3);
    cv::Mat b = cv::Mat(a.rows, a.cols, CV_8UC3);

    b.data = a.data;

    std::cout << "a = " << a << std::endl;
    std::cout << "b = " << b << std::endl;
    std::cout << "a->u = " << a.u << std::endl;
    std::cout << "b->u = " << b.u << std::endl;
    return 0;
}
a = [  0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0]
b = [  0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,   0,   0,   0]
a->u = 000001F31A6F65E0
b->u = 000001F31A6F5FB0

When creating a cv::Mat that shares a pointer to data, what is the recommended writing style?

recommended? to leave u alone. that’s internal plumbing.

I linked the docs for you earlier. Now I’ll quote them:

UMatData* cv::Mat::u

interaction with UMat

that is not something you should touch, not ever.

I asked why you thought you should touch that. I haven’t received an answer yet.

I don’t think u should be manipulated by the programmer; however, I am unsure if u being NULL is correct in this context.

As I mentioned above, I am creating a conversion process between a Windows bitmap and cv::Mat, which requires a pointer to the data to be shared between them.

However, when I define cv::Mat using the constructor cv::Mat(rows, cols, type, *data), the u field, which should contain the matrix metadata, is NULL.

What problems might this cause?
For example, the reference counter within u might have an incorrect value, leading to issues with memory not being freed correctly.

if you want to manipulate the same memory, then yes, you’d use a Mat that doesn’t own its memory. it cannot “manage” that memory.

you can always just copy that Mat. then you have a new Mat that does own its memory. that copy should behave in all the expected ways.

reference counting is a Mat-internal feature that only works on “owned” backing memory, i.e. backing memory that was created by a Mat. this is special. it’s not “arbitrary” memory you pass in as a pointer and size. it’s an actual instance of a class provided by OpenCV.

Thank you. Understood.

So when sharing data, the memory management is not done by cv::Mat, but by the object to which the data is shared.