Using (popular) mexed c++ kdtree from fileexchange leads to Matlab system crashes.
3 views (last 30 days)
Show older comments
I have matlab system errors i.e. total crashes, when I run the following kdtree implementation shared on fileexchange https://ch.mathworks.com/matlabcentral/fileexchange/21512-ataiya-kdtree ; Matlab crashes already for the there provided minimal kdtree_delete_demo.
In this demo
- two cpp files are mexed to provide two separate functions: kdtree_build and kdtree_delete;
- A c++ object is allocated via kdtree_build, and returned as a pointer to matlab
- The c++ object is deleted by a call to kdtree_delete, the pointer is provided as an argument.
When I run it:
- Mexing and creation works fine - apart of a few uninteresting c++ warnings nothing is reported in verbose mex mode.
- The crashes happen upon deletion
- With printouts I was able to pin down that the crash happens as soon as any member of the dereferenced pointer is accessed (namely tree->ndim()).
My question: Could memory persistancy be an issue for this library? As far as I can tell the kdtree library allocates memory in the standard c++ way (new/ ~) without doing any matlab related magic. It is strange that for many the library works fine. I have no experience with mexing, only with c++ and cannot judge if the library has issues or if this example not working means that something is fishy with my whole OS/compilers/system. (Windows 10, Matlab 2016b, Visual studio 2013 c++ professional)
Ps. I cannot easily switch to an alternative kdtree implementation, I try to run code which uses this implementation as 3rd party code, and I really would prefer not to start rewriting this code.
**Update****
Praise goes to Philip Borghesani who found the problem. As visual c++ longs have 4 Byte only, all occurences of long need to be replaced by intptr_t. This need to be done in the files:
- KDTree.h
- kdtree_ball_query.cpp
- kdtree_build.cpp
- kdtree_io_from_mat.cpp
- kdtree_k_neares_neighbors.cpp
- kdtree_nearest_neighbor.cpp
- kdtree_range_query.cpp
Accepted Answer
Philip Borghesani
on 29 Mar 2017
After a quick look at the code I will guess it is not compatible with 64 bit windows. If the objects are allocated at memory addresses below 4gb it might work otherwise this code will cause a crash:
static KDTree* retrieve_pointer(const mxArray* matptr){
// retrieve pointer from the MX form
double* pointer0 = mxGetPr(matptr);
// check that I actually received something
if( pointer0 == NULL )
mexErrMsgTxt("varargin{1} must be a valid kdtree pointer\n");
// convert it to "long" datatype (good for addresses)
long pointer1 = (long) pointer0[0];
// convert it to "KDTree"
KDTree* tree = (KDTree*) pointer1;
// check that I actually received something
if( tree == NULL )
mexErrMsgTxt("varargin{1} must be a valid kdtree pointer\n");
if( tree->ndims() <= 0 )
mexErrMsgTxt("the k-D tree must have k>0");
return tree;
}
The problem is that on win64 long can't store a pointer. It is possible that by changing this line to use size_t or intptr_t and fixing the corresponding code for creating the matptr the code will work but there are most likely other other problems.
Change:
long pointer1 = (long) pointer0[0];
To
intptr_t pointer1 = (intptr_t) pointer0[0];
More Answers (1)
Jnh Zhu
on 8 Apr 2020
我也遇到了类似的问题,matlab运行时kd树时一直提示错误使用 kdtree_nearest_neighbor
vararg{1} must be a [Nxk] matrix of N points in k dimensions。
Thank all of you again and have a nice day!
See Also
Categories
Find more on MATLAB Compiler in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!