Sorry, one minor extension to answer: You might think that your original constructor makes it safe because you make a deep copy of the pointer's contents... but that is the explicit manual constructor. You have not declared the copy-constructor or assignment-constructor, which means C++ will declare them for you and simply make a copy of the pointer addresses...<br>
<br><br><br><div class="gmail_quote">2009/7/28 Paul Harris <span dir="ltr"><<a href="mailto:paulharris@computer.org">paulharris@computer.org</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Looks like Keypoint is being copied. The short, easiest answer is, do option B (see below). Read in detail for more options.<br><br><br>Your constructor is taking ownership of descriptor, and then deleting it on destruction. But what if you do this:<br>
<br>{<br>unsigned int * d = new unsigned int[10];<br><br>Keypoint a(d,10);<br>Keypoint b(a); // copy of a<br><br>} // end of scope, both a and b delete 'd'.<br><br>to resolve this, you either:<br>a) ensure the caller (in this case, main) has ownership, and therefore is in charge of deleting the pointers ONCE.<br>
or<br>b) use a shared_ptr that can handle being copied around<br>or<br>c) avoid all Keypoint copies. either inherit boost::noncopyable or declare the copy-constructor and assignment operator like so...<br><br>struct Keypoint<br>
{<br>blah<br>private:<br> Keypoint operator=(Keypoint const&); // not implemented<br> Keypoint(Keypoint const &); // not implemented<br>};<br><br>that won't compile if there are any copies happening.<br><br>
<br>depending on the application, I would use either A or B. <br><br>A is more manual but if you have a lot of memory to handle then you may want manual control of memory allocs and deallocs. can be the fastest solution.<br>
<br><br>B is very simple to implement...<br>#include <boost/shared_ptr.hpp> // or use the TR1 implementation from your shiny new compiler<br><br>struct Keypoint<br>{<br> shared_ptr<unsigned int> descriptor;<br>
Keypoint(etc etc can either pass in the pointer or shared_ptr, depending on whether you will construct any other Keypoint with the same pointer);<br>NOTE NO destructor required.<br>};<br><br>simple to implement, pretty darn quick, you won't notice the difference and it'll work as expected.<br>
<br><br>option C is the most difficult as MOST STL containers (and KDTree) assume that you can freely copy the items around. so you would have to alter the containers.<br><br><br>I've done a hybrid of A and C before. I alloc the data beforehand (in the stack or vector), pass POINTERS to kdtree to store, and write the kdtree wrappers so that it can handle pointers. (the accessors etc).<br>
<br><br>see ya<br>Paul<br><br><br><br><div class="gmail_quote">2009/7/27 Ingo Jenni <span dir="ltr"><<a href="mailto:ijenni@ee.ethz.ch" target="_blank">ijenni@ee.ethz.ch</a>></span><div><div></div><div class="h5"><br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi everybody!<br>
<br>
I want to insert structures containing a dynamically allocated element into the tree:<br>
<br>
struct Keypoint<br>
{<br>
unsigned int* descriptor;<br>
size_t descLen;<br>
<br>
Keypoint(unsigned int* desc_pt, size_t _descLen)<br>
{<br>
descLen = _descLen;<br>
descriptor = new unsigned int[descLen];<br>
<br>
for(int i = 0; i != descLen; i++)<br>
{<br>
descriptor[i] = desc_pt[i];<br>
}<br>
}<br>
<br>
~Keypoint()<br>
{<br>
delete descriptor;<br>
}<br>
<br>
unsigned int operator[](size_t const N) const {return descriptor[N];}<br>
};<br>
<br>
// Vector access function<br>
unsigned int descAcc(Keypoint k, size_t n)<br>
{<br>
return k[n];<br>
}<br>
<br>
unsigned int* desc1 = new unsigned int[descLen];<br>
unsigned int* desc2 = new unsigned int[descLen];<br>
<br>
Keypoint k1(desc1, descLen);<br>
Keypoint k2(desc2, descLen);<br>
<br>
typedef KDTree::KDTree<descLen, Keypoint, std::pointer_to_binary_function<Keypoint, size_t, unsigned int> > Tree;<br>
<br>
<br>
Tree tree(std::ptr_fun(descAcc));<br>
<br>
tree.insert(k1);<br>
tree.insert(k2);<br>
<br>
Now the first insert works fine, but the second one fails with a crash:<br>
<br>
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x08ff6038 **<br>
<br>
This error does not happen when I comment out the destructor of Keypoint, but that would be the dirty solution by my count :-)<br>
<br>
Does anyone have an idea what's going on here?<br>
<br>
Best regards<br>
Ingo<br>
<br>
<br>
<br>
_______________________________________________<br>
libkdtree-devel mailing list<br>
<a href="mailto:libkdtree-devel@lists.alioth.debian.org" target="_blank">libkdtree-devel@lists.alioth.debian.org</a><br>
<a href="http://lists.alioth.debian.org/mailman/listinfo/libkdtree-devel" target="_blank">http://lists.alioth.debian.org/mailman/listinfo/libkdtree-devel</a><br>
</blockquote></div></div></div><br>
</blockquote></div><br>