Using (popular) mexed c++ kdtree from fileexchange leads to Matlab system crashes.

6 views (last 30 days)
tep
tep on 28 Mar 2017
Commented: FAN ZHANG on 18 Oct 2020
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
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];
  1 Comment
tep
tep on 29 Mar 2017
Thanks a lot for having a look! Now I feel a little bit stupid, because I also thought of the visual c++ oddity (or stupidity) of longs having 4 Byte only, and I thought I excluded it as the error source (I replaced longs by _int64 but intptr_t is a much better choice). As I wanted to document this behaviour with your proposed fix - it turns out it really fixes it -all the demos run! Who knows what I did wrong before.... I'll list all needed changes.
Thank you again and have a great day!

Sign in to comment.

More Answers (1)

Jnh Zhu
Jnh Zhu on 8 Apr 2020
我也遇到了类似的问题,matlab运行时kd树时一直提示错误使用 kdtree_nearest_neighbor
vararg{1} must be a [Nxk] matrix of N points in k dimensions。
非常感谢Philip Borghesani的建议,我将我代码中的long 替换成了 intptr_t便成功了。
Thank all of you again and have a nice day!
  2 Comments
Jnh Zhu
Jnh Zhu on 23 Oct 2020
我调用的kdtree是比较早期的版本了,没替换之前出错语句就是上面说的,用long替换 intptr_t可以解决问题。但我是今年4月在做毕业设计时候才用得到这个的,我自己对这个了解也是不深,可能帮不了您。

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!