Bug detected at Mat class constructor #4: Mat::Mat(int rows, int cols, int type, const Scalar& s); (Bug #4019)


Added by wooden glider over 10 years ago. Updated over 10 years ago.


Status:Cancelled Start date:2014-11-23
Priority:Low Due date:2014-11-24
Assignee:wooden glider % Done:

100%

Category:core
Target version:3.0 Estimated time:0.10 hour
Affected version:branch 'master' (3.0-dev) Operating System:Linux
Difficulty:Easy HW Platform:x86
Pull request:

Description

// the following code will crash at the marked line
int main(int argc, char** argv ) {
printf("hope fine..");
//Mat M = Mat(10, 10, CV_64F);// fine
//Mat M = Mat(10, 10, CV_64F, 0.f);// fine
Mat M = Mat(10, 10, CV_64F, 0);// declare a float matrix but sends an type-unclear scalar
//Mat M = Mat(10, 10, CV_32F, 0);// same as above
M.at<double>(0, 0) = 0.f;// [mark] crashes at here, where a float is assigned to an entry of matrix. it seems that the initial scalar 0 is miss translated to an integer
printf("Okay!");
return 0;
}
// Reappearrance:
// as described above, if, the constructor is initialized using a specific type, (namely float), but is initialized with a value of unclear type, (for e.g. 0, which can be both traslated to float (0.f) or integer (0)). then, the initial scalar 0 will seems to be miss translated to an integer, causing further crash when the entry is assigned a float. the crash is uncaptured and terminal returns segmentation fault.
// (my) Analysis
// in the constructor, matrix is allocated space if initial scalar is specified. if initial scalar is float (4 Byte per entry) and assigned an integer (2 Bytes per entry), then it is okey, but if initial scalar is integer (2 Bytes per entry) and assigned an float (4 Bytes per entry) it causes crash due to memory out of bound.
// Suggestion
// so (i think) it is the result of type miss translation. if the matrix space is allocated according to the 3rd parameter (int type) instead 4th, it might be less confusing and (hope) works fine.
// hope helpful. --xianglin01


History

Updated by be rak over 10 years ago


    Mat M = Mat(10, 10, CV_64F, 0); 

the 0 is interpreted as a (null)pointer, not as a Scalar, so no memory was allocated.

http://docs.opencv.org/modules/core/doc/basic_structures.html#Mat::Mat(int%20rows,%20int%20cols,%20int%20type,%20void*%20data,%20size_t%20step)

you probably wanted:


    Mat M = Mat(10, 10, CV_64F, Scalar(0)); 

Updated by wooden glider over 10 years ago

be rak wrote:

[...]

the 0 is interpreted as a (null)pointer, not as a Scalar, so no memory was allocated.

http://docs.opencv.org/modules/core/doc/basic_structures.html#Mat::Mat(int%20rows,%20int%20cols,%20int%20type,%20void*%20data,%20size_t%20step)

you probably wanted:

[...]

that is reasonable. thanks for mentioning that Scalar(), which is useful. but when a 1.0f or 1.f or any other value is sent as a scalar, it works just fine, so I think that when an 0 (or 0.0, 0.f) is sent, it should be translated as a scalar too, just like the other values do.
moreover, if a coder (such as me) want to declare a Mat object without allocating any memory, one would not sent in the 4th parameter, just for simplifing the code; if one sent in a value, then it supposed to be translated as a value, causing less confusion about value 0.0, 0.f, 0.0f and 0 itself.

further testing:

// the following code will crash at the marked line
int main(int argc, char** argv ) 
{
  printf("more test is assigned..");
  //Mat M = Mat(10, 10, CV_64F);// fine
  //Mat M = Mat(10, 10, CV_64F, 1.0);// fine
  //Mat M = Mat(10, 10, CV_64F, 1.f);// fine
  //Mat M = Mat(10, 10, CV_64F, 0.0);// fine
  //Mat M = Mat(10, 10, CV_64F, 0.f);// fine
  Mat M = Mat(10, 10, CV_64F, 0);// not fine. (declare a float matrix but send a type-unclear scalar)
  M.at<double>(0, 0) = 0.f;// [mark] fails at here! where a float is assigned to an entry of matrix. it seems that
                           //        refers to rak, the initial scalar 0 is miss translated to null pointer
  printf("Okay!");
  return 0;
}

my suggestion remained, and put it simply, if the matrix type is defined according to the 3rd parameter (int type) instead 4th, it should work just fine, if I am right.
hope helpful. --xianglin01

Updated by wooden glider over 10 years ago

  • % Done changed from 20 to 30

Updated by Alexander Alekhin over 10 years ago

  • Assignee deleted (Alexander Alekhin)

Updated by wooden glider over 10 years ago

  • Assignee set to Alexander Alekhin

Updated by wooden glider over 10 years ago

  • Assignee changed from Alexander Alekhin to Alexander Karsakov

Updated by Alexander Karsakov over 10 years ago

Hi wooden glider!

It's not a bug. But it can be useful, you may implement this functionality and send pull request to us (http://code.opencv.org/projects/opencv/wiki/How_to_contribute).

  • Status changed from New to Cancelled
  • Assignee changed from Alexander Karsakov to wooden glider
  • Priority changed from Normal to Low

Updated by wooden glider over 10 years ago

hi Alexander Alekhin, thanks for response and suggestions!

Updated by wooden glider over 10 years ago

Alexander Karsakov wrote:

Hi wooden glider!

It's not a bug. But it can be useful, you may implement this functionality and send pull request to us (http://code.opencv.org/projects/opencv/wiki/How_to_contribute).

Hi Alexander Karsakov!
Thanks for your appreciation! I'll try my best to submit a pull request.

Updated by wooden glider over 10 years ago

  • % Done changed from 30 to 40

Updated by wooden glider over 10 years ago

  • % Done changed from 40 to 50

Updated by wooden glider over 10 years ago

  • % Done changed from 50 to 60

Updated by wooden glider over 10 years ago

  • % Done changed from 60 to 70

Updated by wooden glider over 10 years ago

I studied this issue, and find that the origin of this issue is the interfere between constructors #4 and #7:

Mat::Mat(int rows, int cols, int type, const Scalar& s)

Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step = AUTO_STEP)

http://docs.opencv.org/modules/core/doc/basic_structures.html#Mat.
simply reorganize the parameter list of either of them can have the problem solved. however because this involves interface changes, so wish there might be a better solution.

  • Status changed from Cancelled to Done
  • % Done changed from 70 to 100

Updated by wooden glider over 10 years ago

  • Status changed from Done to Cancelled

Also available in: Atom PDF