[shifted_ptr][3.0] Important bugs fixes

Greetings: I have made many bug fixes to the library and it now runs properly a previous example requested. The code is much more robust and I would like requesting everyone to replace any 2.x series with this one. There is unfortunately a situation on MSVC when shifted_ptr<> is used with arrays. I believe there is an array to pointer to array convertion problem at runtime (inside new_sh) but this issue needs to be further investigated. I disabled array functionality for MSVC until it can be fixed. Everything works fine under GCC. Regards, -Phil

AMDG Phil Bouchard wrote:
Greetings:
I have made many bug fixes to the library and it now runs properly a previous example requested. The code is much more robust and I would like requesting everyone to replace any 2.x series with this one.
There is unfortunately a situation on MSVC when shifted_ptr<> is used with arrays. I believe there is an array to pointer to array convertion problem at runtime (inside new_sh) but this issue needs to be further investigated. I disabled array functionality for MSVC until it can be fixed. Everything works fine under GCC.
I'm checking it out now. Here's a warning that can easily be fixed: warning C4100: 'ti' : unreferenced formal parameter shifted_ptr\shifted_ptr\boost\detail\sh_owned_base_nt.hpp 144 In Christ, Steven Watanabe

AMDG Phil Bouchard wrote:
Greetings:
I have made many bug fixes to the library and it now runs properly a previous example requested. The code is much more robust and I would like requesting everyone to replace any 2.x series with this one.
There is unfortunately a situation on MSVC when shifted_ptr<> is used with arrays. I believe there is an array to pointer to array convertion problem at runtime (inside new_sh) but this issue needs to be further investigated. I disabled array functionality for MSVC until it can be fixed. Everything works fine under GCC.
I noticed that you included a modified form of my list example. It is not equivalent. Because you are not setting front in insert(), the test if(front.get() == 0) will always be true. As a result the list will always have size 1 which defeats the purpose of the test. The original crashes on msvc 9.0. HEAP[shifted_ptr.exe]: HEAP: Free Heap block 3f6680 modified at 3f66ac after it was freed In Christ, Steven Watanabe

"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:4810B429.4090008@providere-consulting.com... [...]
I noticed that you included a modified form of my list example. It is not equivalent. Because you are not setting front in insert(), the test if(front.get() == 0) will always be true. As a result the list will always have size 1 which defeats the purpose of the test. The original crashes on msvc 9.0.
HEAP[shifted_ptr.exe]: HEAP: Free Heap block 3f6680 modified at 3f66ac after it was freed
Yeah I'll fix that tonight quickly, my mistake. -Phil

"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:4810B429.4090008@providere-consulting.com... [...]
I noticed that you included a modified form of my list example. It is not equivalent. Because you are not setting front in insert(), the test if(front.get() == 0) will always be true. As a result the list will always have size 1 which defeats the purpose of the test. The original crashes on msvc 9.0.
HEAP[shifted_ptr.exe]: HEAP: Free Heap block 3f6680 modified at 3f66ac after it was freed
This is a nasty bug because everything is processed like it should but crashes and ends differently with various debuggers. On MSVC it crashes on the deletion of the last object of type "owned<node>" but the pointer is perfectly valid. I'll check this out again this weekend. -Phil

AMDG Phil Bouchard wrote:
"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:4810B429.4090008@providere-consulting.com...
[...]
I noticed that you included a modified form of my list example. It is not equivalent. Because you are not setting front in insert(), the test if(front.get() == 0) will always be true. As a result the list will always have size 1 which defeats the purpose of the test. The original crashes on msvc 9.0.
HEAP[shifted_ptr.exe]: HEAP: Free Heap block 3f6680 modified at 3f66ac after it was freed
This is a nasty bug because everything is processed like it should but crashes and ends differently with various debuggers. On MSVC it crashes on the deletion of the last object of type "owned<node>" but the pointer is perfectly valid.
I'll check this out again this weekend.
The problem is that you are manipulating the reference count of a block after it is freed. The first node is deleted. The second node is then deleted which decrements the reference count of the first block which is already deleted. Here's the stack trace at the point the error actually occurs. shifted_ptr.exe!boost::detail::sp_counted_base::release() Line 77 C++ shifted_ptr.exe!boost::detail::sh::shifted_ptr_base<node>::~shifted_ptr_base<node>() Line 131 C++ shifted_ptr.exe!boost::detail::sh::shifted_ptr<node,boost::detail::sh::shifted_ptr_base>::~shifted_ptr<node,boost::detail::sh::shifted_ptr_base>() Line 238 + 0xf bytes C++ shifted_ptr.exe!node::~node() Line 19 + 0x1a bytes C++ shifted_ptr.exe!node::`scalar deleting destructor'() + 0x2b bytes C++ shifted_ptr.exe!boost::detail::sh::owned<node>::dispose<node>(node * p=0x003f67f8, const boost::integral_constant<bool,0> & __formal={...}) Line 186 C++ shifted_ptr.exe!boost::detail::sh::owned<node>::dispose() Line 142 + 0x38 bytes C++ shifted_ptr.exe!boost::detail::sh::owned<node>::~owned<node>() Line 141 + 0x5a bytes C++ shifted_ptr.exe!boost::detail::sh::owned<node>::`scalar deleting destructor'() + 0x2b bytes C++ shifted_ptr.exe!boost::detail::sh::set::release() Line 89 + 0x39 bytes C++ shifted_ptr.exe!boost::detail::sh::shifted_ptr<node,boost::detail::sh::shifted_ptr_base>::release(bool d=false) Line 246 + 0xb bytes C++ shifted_ptr.exe!boost::detail::sh::shifted_ptr<node,boost::detail::sh::shifted_ptr_base>::reset() Line 233 C++ shifted_ptr.exe!list::clear() Line 33 C++ shifted_ptr.exe!main() Line 56 C++ shifted_ptr.exe!__tmainCRTStartup() Line 582 + 0x19 bytes C shifted_ptr.exe!mainCRTStartup() Line 399 C kernel32.dll!7c816fd7() [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] In Christ, Steven Watanabe

"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:481236C2.2040309@providere-consulting.com... [...]
The problem is that you are manipulating the reference count of a block after it is freed. The first node is deleted. The second node is then deleted which decrements the reference count of the first block which is already deleted.
[...] Thanks for pointing this out. I dismissed this issue because it this situation the "back" pointer doesn't refer to the first element in the set list after several insertions and this creates a series of problems which may have a solution but better left aside for this type of problem. I added some code in shifted_ptr::release() which will make it disregard any reference count when the destructor is called upon a set deletion. Now everything works fine. Regards, -Phil

AMDG Phil Bouchard wrote:
"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:481236C2.2040309@providere-consulting.com...
[...]
The problem is that you are manipulating the reference count of a block after it is freed. The first node is deleted. The second node is then deleted which decrements the reference count of the first block which is already deleted.
[...]
Thanks for pointing this out. I dismissed this issue because it this situation the "back" pointer doesn't refer to the first element in the set list after several insertions and this creates a series of problems which may have a solution but better left aside for this type of problem.
I added some code in shifted_ptr::release() which will make it disregard any reference count when the destructor is called upon a set deletion. Now everything works fine.
I'm thinking that the cleanest solution will be to have set deletion split the cleanup into first calling all the objects' destructors and then freeing all the memory. When the objects are destroyed you should increment the reference count to make sure that the objects are not destroyed again. When you actually release the memory you can then verify that the reference count is 1, and thus that all references to the object come from within the set. Otherwise, looking at your current implementation, it looks like shifted_ptr's on the heap will never clean up the object pointed to until the set goes away. In Christ, Steven Watanabe

"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:48178BBA.3050100@providere-consulting.com... [...]
I'm thinking that the cleanest solution will be to have set deletion split the cleanup into first calling all the objects' destructors and then freeing all the memory. When the objects are destroyed you should increment the reference count to make sure that the objects are not destroyed again. When you actually release the memory you can then verify that the reference count is 1, and thus that all references to the object come from within the set.
Otherwise, looking at your current implementation, it looks like shifted_ptr's on the heap will never clean up the object pointed to until the set goes away.
That's funny because actually I forgot adding a U<T>::reset() statement before set::release() inside shifted_ptr::release() in the code I submitted yesterday. I wanted to change it quickly but not on time. Now the first element in the set being deleted is the one pointed to by po_; -Phil

"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:48178BBA.3050100@providere-consulting.com... [...]
I'm thinking that the cleanest solution will be to have set deletion split the cleanup into first calling all the objects' destructors and then freeing all the memory. When the objects are destroyed you should increment the reference count to make sure that the objects are not destroyed again. When you actually release the memory you can then verify that the reference count is 1, and thus that all references to the object come from within the set.
Otherwise, looking at your current implementation, it looks like shifted_ptr's on the heap will never clean up the object pointed to until the set goes away.
Great news...! I just tried it this way and it works perfectly. The set elements are now following the destruction hierarchy properly which is very nice. I have changed: set::release() and removed U<T>::po_ = 0 in shifted_ptr::release() when an element on the heap is being deleted, which was basically a brute force deletion avoiding recursive problems. But the sequence order doesn't guarantee the element pointed to by po_ will be the first to be deleted. I tried different alternatives and ended with unwanted behaviors so I kept it this way until I work on it again. The library isn't in the Sandbox yet but should be there quickly enough. Bests, -Phil
participants (2)
-
Phil Bouchard
-
Steven Watanabe