Date: Wed, 17 Jul 2024 01:12:18 +0200
On 7/16/24 23:13, M.C.A. (Marco) Devillers via Std-Proposals wrote:
> Because C++ smart pointers are based on RAII it is easy to trigger an
> overflow of the C stack since destructors call each other. Smart
> pointers are supposed to be safe, smart pointers are likely to be used
> extensively in the future, and this behaviour could make a large
> number of C++ programs core dump unexpectedly.
> This proposal is to remove this behaviour from GCCs standard library
> and also showcases a small trick by which that can be done.
So the problem is that your data structure (list_node) keeps a linked
list of smart pointers, and the destructor invokes the destructor of the
nested data structure, which invokes the destructor of... etc. causing
a stack overflow.
Your solution is to push the nested destructors onto a global container
thus putting them on the free store (heap) during destruction, and then
destroy the elements from this container.
A more efficient solution is to break the chain inside the destructor.
Something like this (warning: off the top of my head)
struct list_node {
using ptr = std::unique_ptr<list_node>;
~list_node() {
while (next)
{
auto node = next.release();
next = std::move(node->next);
delete node;
}
}
int x;
ptr next;
};
> Because C++ smart pointers are based on RAII it is easy to trigger an
> overflow of the C stack since destructors call each other. Smart
> pointers are supposed to be safe, smart pointers are likely to be used
> extensively in the future, and this behaviour could make a large
> number of C++ programs core dump unexpectedly.
> This proposal is to remove this behaviour from GCCs standard library
> and also showcases a small trick by which that can be done.
So the problem is that your data structure (list_node) keeps a linked
list of smart pointers, and the destructor invokes the destructor of the
nested data structure, which invokes the destructor of... etc. causing
a stack overflow.
Your solution is to push the nested destructors onto a global container
thus putting them on the free store (heap) during destruction, and then
destroy the elements from this container.
A more efficient solution is to break the chain inside the destructor.
Something like this (warning: off the top of my head)
struct list_node {
using ptr = std::unique_ptr<list_node>;
~list_node() {
while (next)
{
auto node = next.release();
next = std::move(node->next);
delete node;
}
}
int x;
ptr next;
};
Received on 2024-07-16 23:12:26