-
Notifications
You must be signed in to change notification settings - Fork 751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OpenCV: avoiding memory corruption when using Mat constructors taking primitive arrays #1002
Conversation
opencv/src/main/java/org/bytedeco/opencv/presets/opencv_core.java
Outdated
Show resolved
Hide resolved
Instead of only adding warnings like you did, could you instead add a |
Good idea. Another possible addition : constructors taking 2D Java arrays ? |
Hmm, forget my remark, Points and Scalars can be arbitrarily long. So 18 overloads ? |
Why not? :) It's just like
No, that would break backward compatibility and it doesn't work well in our case where everything is a Pointer and which constructor might get used isn't always clear.
Yes, of course, there's a lot we can do :) |
BTW, since this is just Java code, we can use for loops and what not to generate code more easily, for example, like this: |
In the constructors taking pointers, if the pointers'limit equals the position, the length is set to 1. |
I suppose we could leave that to 0? That's probably going to throw some exception, which would be acceptable. |
Pointers may have a limit of 0 when it's unknown (that seems to be the case of See new proposal with |
Except for a couple of small mistakes in the comments, looks good! To be consistent with the rest of JavaCPP though, instead of throwing an exception, let's saturate sizes this way: |
I'm not aware of the consistency problem, but saturation would yield something like:
silently creating a mat of length 0x7FFFFFFF instead of throwing an exception. Is this really why is preferred ? |
I like it better that way anyway, less exceptions to worry about :) It's handled like that everywhere else in JavaCPP and I never heard anyone having any problems with it. Containers like that don't support large enough indices, so the user will get into trouble trying to index those with |
@HGuillemet Please let me know if that looks good enough and all correct! Thanks |
org.bytedeco.opencv.presets.opencv_core.java
defines Mat constructors taking either a java array (var args) or aPointer
.Concerning arrays, one can write :
and, since 1D matrices are not what is needed most of the time, one is tempted to do:
This looks practical and quite armless for anyone used to OpenCV patterns but leads to memory corruption since this Mat constructor actually allocates a buffer, copies the Java array to the buffer, and creates an OpenCV Mat header pointing to this (opencv-external) data. A pointer to the buffer is kept in the Mat object, but when the Mat is garbage collected, the buffer is collected to and the buffer is freed. The reshaped Mat then points to a deallocated buffer.
This PR replaces the Java-side allocation by the allocation of a normal OpenCV Mat, that would benefit from OpenCV reference counting feature. There is no performance loss since we copy the data in both cases.
Concerning Mat constructors taking a
Pointer
as argument, they suffer from the same dangerous limitation. This PR simply adds a warning comment since creating a Mat from a Pointer enables the option to apply opencv processing to any kind of data without memory copy.