Home > Back-end >  double free detected in tcache 2 when calling erase() on std::set
double free detected in tcache 2 when calling erase() on std::set

Time:03-17

i was writing a simple code for testing purposes. if i declare the node1 first, there's no problem but when i declare the node2 first, the code give me free(): double free detected in tcache2.

  • could someone please explain the reason for this double free error?

    class node1;
    class node2;
    
    class node1{
     public:
         node1(void) = default;
    
         // member data
         int *n;
         std::set<node2*> tonode2;
    };
    
    class node2{
     public:
         node2(void) = default;
    
         ~node2(void){
             for(auto val:tonode1)
                 val->tonode2.erase(this);           // free(): double free detected here..
         }
    
         // member data
         int *n;
         std::set<node1*> tonode1;
    };
    
    int main(void){
       node2 n2;
       node1 n1;
    
       n1.tonode2.insert(&n2);
       n2.tonode1.insert(&n1);
    
       return 0;
     }
    

the code compiled with g (GCC) 11.2.0 run on ubuntu 20.04.

CodePudding user response:

n1 is destroyed first. When n2 is destroyed, its destructor will indirect through the pointer that used to point to n1, but is now invalid. The behaviour of the program is undefined.

CodePudding user response:

You better use smart pointers such as std::shared_ptr instead of raw pointers when ownership is important. std::weak_ptr should be preferred if there are reference cycles as in your question.

And you should create them with std::make_shared in the main, so that objects will be owned by smart pointer. Because smart pointers assume they are the only owner of the enclosed object. Otherwise it will be destructed two times, once by the owner scope and once by the smart pointer, leading to a double free corruption.

  • Related