Using (popular) mexed c++ kdtree from fileexchange leads to Matlab system crashes.
3 次查看(过去 30 天)
显示 更早的评论
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
采纳的回答
Philip Borghesani
2017-3-29
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 个)
Jnh Zhu
2020-4-8
我也遇到了类似的问题,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!
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!