This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Segmentation fault with unique_ptr
- From: Mikhail Maltsev <maltsevm at gmail dot com>
- To: tassos_souris <tassos_souris at yahoo dot gr>
- Cc: gcc mailing list <gcc at gcc dot gnu dot org>
- Date: Sun, 15 Feb 2015 19:28:30 +0300
- Subject: Re: Segmentation fault with unique_ptr
- Authentication-results: sourceware.org; auth=none
- References: <1423826115745-1120921 dot post at n5 dot nabble dot com> <54DDDF7D dot 7000803 at arm dot com> <1423832652181-1120949 dot post at n5 dot nabble dot com>
13.02.2015 16:04, tassos_souris writes:
> Compile with: g++-4.9 -std=c++14 -g -o main main.cpp
> and run with ./main. I get segfault. gdb in bt shows that the segfault
> happens inside unique_ptr destructor. So it is not a memory issue.
> Also since the code runs with less size (i.e size=1000 no problem) i assume
> that something is wrong with unique_ptr and not my code. That's of course
> only an assumption don't get me wrong :)
The destructor of struct node calls the destructor of it's "next" member,
which is std::unique_ptr<node>, so you get a chain of recursive calls, and
when it gets too deep, you simply run out of stack (you could check it by
setting a breakpoint on node::~node and stepping through it several times,
looking at the backtrace each time).
Here is what I get with GCC 4.8.2, -std=c++11:
#0 singly_linked_list_2::node::~node (this=0x6511b0, __in_chrg=<optimized out>) at ./stack_fail.cc:8
#1 0x0000000000400db8 in std::default_delete<singly_linked_list_2::node>::operator() (this=0x6511d8, __ptr=0x6511b0) at /usr/include/c++/4.8.2/bits/unique_ptr.h:67
#2 0x0000000000400a07 in std::unique_ptr<singly_linked_list_2::node, std::default_delete<singly_linked_list_2::node> >::~unique_ptr (this=0x6511d8, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/unique_ptr.h:184
#3 0x0000000000400d94 in singly_linked_list_2::node::~node (this=0x6511d0, __in_chrg=<optimized out>) at ./stack_fail.cc:8
#4 0x0000000000400db8 in std::default_delete<singly_linked_list_2::node>::operator() (this=0x6511f8, __ptr=0x6511d0) at /usr/include/c++/4.8.2/bits/unique_ptr.h:67
#5 0x0000000000400a07 in std::unique_ptr<singly_linked_list_2::node, std::default_delete<singly_linked_list_2::node> >::~unique_ptr (this=0x6511f8, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/unique_ptr.h:184
#6 0x0000000000400d94 in singly_linked_list_2::node::~node (this=0x6511f0, __in_chrg=<optimized out>) at ./stack_fail.cc:8
#7 0x0000000000400db8 in std::default_delete<singly_linked_list_2::node>::operator() (this=0x651218, __ptr=0x6511f0) at /usr/include/c++/4.8.2/bits/unique_ptr.h:67
#8 0x0000000000400a07 in std::unique_ptr<singly_linked_list_2::node, std::default_delete<singly_linked_list_2::node> >::~unique_ptr (this=0x651218, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/unique_ptr.h:184
#9 0x0000000000400d94 in singly_linked_list_2::node::~node (this=0x651210, __in_chrg=<optimized out>) at ./stack_fail.cc:8
#10 0x0000000000400db8 in std::default_delete<singly_linked_list_2::node>::operator() (this=0x7fffffffe410, __ptr=0x651210) at /usr/include/c++/4.8.2/bits/unique_ptr.h:67
#11 0x0000000000400a07 in std::unique_ptr<singly_linked_list_2::node, std::default_delete<singly_linked_list_2::node> >::~unique_ptr (this=0x7fffffffe410, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/unique_ptr.h:184
#12 0x0000000000400962 in singly_linked_list_2::~singly_linked_list_2 (this=0x7fffffffe400, __in_chrg=<optimized out>) at ./stack_fail.cc:19
#13 0x00000000004007ae in main () at ./stack_fail.cc:40
As we see, the recursion depth is linear WRT list size.
At higher optimization levels the tail call gets optimized, and this problem
does not occur, but in general it's better not to rely on this.
--
Regards,
Mikhail Maltsev