Click here to Skip to main content
15,881,757 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am creating just a simple forward directional Link List, which uses STL's Shared Pointers to handle the dynamic memory. However, I am coming across a stack overflow error. Basically I have a 'node' structure that has a shared pointer to another 'node' type and a data type to hold the users data. I am then continually adding other nodes to this shared pointer. I am noticing that when the Shared Pointers start to destroy themselves, the beginning node keeps calling its inner nodes destructor before completely destroying itself, which eventually results in a stack overflow. I am wondering if anyone has an idea on how to eliminate this stack overflow? It would be nice to get the Shared Pointers to start deleting from the most recently added pointer. I hope this question was clear, please let me know.

Thanks,
robNO.
Posted
Comments
RobNO 29-Jan-12 9:16am    
I figured out a solution, however, I am not sure if it is the best one. In my List destructor I just start unattaching the shared points at the tail of the list, thus eliminating stack overflow because the Shared Pointer will delete one at a time rather than trying to delete them all at once. If anyone has other suggestion i would like to hear them,

Thanks,
robNO,

It is a typical problem mainly due to the fact that the heap is greater than the stack, and a heap-based recursive structure is deallocated with a nested (recursive) function call (the dtors, in your case).

A way to avoid this problem is delete the node iteratively, not by recursion.


C++
class A
{
    std::shared_ptr<A> next;
public:
    ~A()
    {
       while(next)
       {
           std::shared_ptr<A> killer;
           std::swap(killer, next); //next now null, our next is in killer
           std::swap(killer->next, next) //killer->next null, its next is our next
       }   //killer destroyed, *killer deleted
    }
}
 
Share this answer
 
Comments
RobNO 29-Jan-12 13:04pm    
Thanks For your Reply!
This works great! Much better than my solution because then the Nodes them selves will handle there own deallocation!
Thanks for your time!
robNO.
Albert Holguin 29-Jan-12 19:25pm    
Curious... at this point, wouldn't it just be easier to not use shared_ptr for this?
Emilio Garavaglia 30-Jan-12 2:38am    
I started considering the user's choice does not depend ONLY on that.
May be shared_ptr is used because the A objects are not only forming a chain (in that case killer will not kill anything: will just let the object with one reference less).

If the problem was just "chaining", than unique_ptr will suffice.
An if the polymorphic deletion of STL smart-pointer is retained too costly, a regular pointer into A with proper move semantics will be at the minimum cost.
RobNO 31-Jan-12 12:31pm    
Thanks for your reply!
Sorry, for the late reply. So I am actually making a double LinkList and I have it set up so the next pointer uses shared_ptr and the prev pointer uses weak_ptrs. Could I have done this with unique_ptr or raw pointers? If so what are the pros and cons.
Thanks,
robNO!
Emilio Garavaglia 31-Jan-12 13:07pm    
That's not an easy answer, without a knowledge of what they are for.

In general I avoid using my own lists in favor of std::list (unless the "list" is intrusive in respect to components). But it's not a response for a comment. There can be articles on that subject.
If the source of your stack overflow is your custom list, you can eliminate the stack overflow by using std::list, unless there is a compelling reason not to - in which case, I assume you would have mentioned it.

Shared pointers delete the encapsulated pointer whenever their reference count is zero: if the parent node deletes memory already deleted, apparently it holds a dumb pointer to memory that is also encapsulated in a shared::ptr. Mixing smart and dumb pointers is a bad thing.

Hope this helps,
 
Share this answer
 
Comments
RobNO 29-Jan-12 9:12am    
Thanks for the reply!!!
Yes there is a reason why I am not using the built in STL collections, however, I don't want to get into much detail about that. Can You elaborate on what a dumb pointer is? Are you just referring to a raw pointer, If so I am not mixing raw and shared pointers, I am too much of a novice and do not have the time to deal with the complications of a raw pointer.
Thanks,
robNO.
Pablo Aliskevicius 29-Jan-12 9:47am    
A dumb pointer it the opposite of a smart pointer: char * is a dumb pointer. Raw pointers are the same thing.
The reason why you're not using STL collections is relevant: if I was new to C++, I wouldn't try to improve on Stepanov's work. I don't want to get into much detail about why this is very relevant.

Good luck,
RobNO 29-Jan-12 11:49am    
I am attempting to build something known as a squarelist for a school project if you really want to know. Using STL is rather inefficient for the implementation for this project and there will be a considerable mark deduction if STL containers are used. I have almost three years of post-secondary experience with c++.
Pablo Aliskevicius 29-Jan-12 12:02pm    
Ok, then I'd suggest you to write your own version of shared_ptr, writing something to the console in both the constructor and the destructor (for instance, the inner raw pointer and the reference count). Also, write to the console whenever your list is trying to release a pointer, and see whether they're released twice.

I also see that you figured a solution, if it works - keep it.

Hope this helps,
RobNO 29-Jan-12 12:04pm    
Thanks for your time Pablo!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900