c++opencvmat

Why OpenCV Mat no index out of bounds?


I'm using OpenCV 4.5.1 and really confuse about this condition: So I just create a new Mat object:

Mat model_Input = (Size(5, 1), CV_32FC1);

then I try to input some value in A by using Mat.at, like:

model_Input.at<float>(0, 0) = 1.0;
model_Input.at<float>(0, 1) = 2.0;
model_Input.at<float>(0, 2) = 3.0;
model_Input.at<float>(0, 3) = 4.0;
model_Input.at<float>(0, 4) = 5.0;
model_Input.at<float>(0, 5) = 6.0;

It seems like the code model_Input.at<float>(0, 5) = 6.0; out of the bounds (Size(5,1))?

But no error was reported during the compilation process, and there is no problem even when debug. The Mat model_Input for sure only have 5 values since I try to cout it, but I don't know why no errors in this code?


Solution

  • Compilation phase:

    no error was reported during the compilation process

    A cv::Mat can have a dynamic size. It can even be changed after construction e.g. with cv::Mat::reshape and cv::Mat::resize.
    Therefore there is no way that the compiler can in general detect out-of-bound access.

    As for runtime:

    Accessing data out-of-bounds is generally an Undefined Behavior by the C++ standard. It means that anything can happen, including (but not necessarily) a crash.

    there is no problem even when debug

    I don't think this is correct:
    Although it is not demanded by the C++ standard in any way, if you build your program with opencv in Debug mode you should see an assertion failure at runtime, because cv::Mat::at performs bounds check in Debug:

    For the sake of higher performance, the index range checks are only performed in the Debug configuration.

    You should get something like the following (I am using 4.8.0 but you should get something similar in your version):

    OpenCV(4.8.0) Error: Assertion failed ((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())) in cv::Mat::at, file C:\Dev\opencv-4.8.0-windows\build\include\opencv2\core\mat.inl.hpp, line 899
    

    A side note:
    Mat model_Input = (Size(5, 1), CV_32FC1); is not valid syntax. You probably have something like Mat model_Input(Size(5, 1), CV_32FC1);.