0

I have problems understanding why the following code always throws this exception:

AddressSanitizer: attempting double-free

I guess I'm not getting some part of the new/delete process, but just can't figure it out.

Thanks for any help in advance guys... ..or girls;P

#include <iostream>
using namespace std;

template <typename Key, size_t N >
class TSet {
    struct Thing; using Link = Thing *;
    struct Thing{
        Key key;
        Link link{nullptr};
        ~Thing(){ if (link){ delete[] link; link=nullptr; }}
    };
    Link root{nullptr};
    size_t size;

    void    addB_Sub(Link e){ 
        if ( e->link ) { addB_Sub(e->link); }
        else e->link= new Thing[N];
    }
public:
    TSet(): root{new Thing[N]}, size{N} {}
    ~TSet(){  delete[] root; }//if (root)

    void    addB(const size_t &i){ addB_Sub(root+i); }

std::ostream &show(std::ostream &o) {
        if (!(root)) return o;
        Link peak;
        size_t count;
        for (size_t i{size}; i--; ) { cout<<'['<<i<<']';
            count=0;
            peak=(root+i);
            while (peak->link) { ++count; peak=peak->link; }
            o<<count<<", ";
        }
        cout<<"end";
        peak=nullptr;
        return o;
    }
};
template <typename Key, size_t N>
std::ostream &operator<<(ostream& o,TSet<Key, N> g){ return g.show(o); } 

int main(){
    TSet<int,5> s;
    for (int i{7}; i>0; --i) s.addB(1);
    for (int i{4}; i>0; --i) s.addB(3);
    for (int i{2}; i>0; --i) s.addB(4);
    cout<<s<<endl;
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
mcaustria
  • 123
  • 6
  • Inside a destructor, all of `if (link){ delete[] link; link=nullptr; }` can and *should* simply be written as `delete[] link;`. The rest is redundant and signals the wrong intent. – Konrad Rudolph May 24 '20 at 13:31

1 Answers1

0

Your issues is partially here:

template <typename Key, size_t N>
std::ostream &operator<<(ostream& o, TSet<Key, N> g);

You take argument by value, so you do copy.

Your real issue is that your classes doesn't respect rule of 3/5/0.

So both g destructor and s destructor release the same resources.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • ooooh...i only copuy the pointer not the pointed object....i get it, thanX a lot!! ..and rule of 3/5/0 really makes sense here, thanks again! – mcaustria May 24 '20 at 14:00