ramgorur
ramgorur

Reputation: 2164

c++ how to free a static reference to an outside object?

First you need to look into this code, here I have two classes -- one is the TreasureBag and the other is the Sprite. I have multiple copies of sprite but there is only one bag (hence it's static). The sprites acquire the bag and collect treasures, store inside it, then the next sprite comes and use it for treasure collection.

Here is my code --

class TreasureBag {
    private:
        int* bag ; int size ; int index ;

    public:
        TreasureBag(int size = 10) {
            this->index = 0 ; this->size = size ;
            this->bag = new int[this->size] ;
        }
        ~TreasureBag() { delete [] this->bag ; }
        void put(int data) { this->bag[this->index++] = data ;}
        friend ostream& operator<< (ostream &os, const TreasureBag &tb);
};

class Sprite 
{
    private:
        static TreasureBag tbag ; int points = 0 ; string name ;

    public:
        Sprite(string name) { this->name = name ; }
        ~Sprite() { ; } // --> not sure what to do here
        void collect(int data) { this->tbag.put(data); }
        void acquireTreasureBag(TreasureBag &tb) { Sprite::tbag = tb ; }
        void releaseTreasureBag() { ; } // ---> not sure what to do here either
        friend ostream& operator<< (ostream& os, const Sprite &s);
};
TreasureBag Sprite::tbag ;

Inside the main, I have two sprites s1 and s2, and one treasure bag. The sprite s1 comes first, grabs it and put stuffs inside, then it releases the bag and s2 acquires it.

int main()
{
    TreasureBag tb(5) ; Sprite s1("s1");
    s1.acquireTreasureBag(tb); // <-- Looks like this line is problematic

    /*s1.collect(1); s1.collect(2);
    cout << s1 << endl ;
    s1.releaseTreasureBag();

    Sprite s2("s2"); s2.acquireTreasureBag(tb);
    s2.collect(3);
    cout << s2 << endl ;*/
    return 0 ;
}

But when I run the code (please see the un-commented lines), I get this error --

*** Error in `./a.out': double free or corruption (fasttop): 0x0000000002495040 ***
Aborted (core dumped)

What is the best way to handle this kind of situation? Is my design principle ok? Moreover, I am not sure what I should do in the sprite destructor ~Sprite() and the releaseTreasureBag() procedure.

please help.

Upvotes: 0

Views: 97

Answers (2)

Jarod42
Jarod42

Reputation: 217275

You don't respect rule of three (or Five). Use std::vector to avoid to manage memory yourself:

class TreasureBag {
private:
    std::vector<int> bag;
    int max_size;

public:
    TreasureBag(int size = 10) : max_size(size) {}
    void put(int data) { if (bag.size() < max_size) bag.push_back(data) ;}
public:
    friend ostream& operator<< (ostream &os, const TreasureBag &tb);
};

Upvotes: 3

Barry
Barry

Reputation: 303027

It seems like you might want to use smart pointers for this:

class Sprite {
    static std::shared_ptr<TreasureBag> tbag;

public:
    void acquire(std::shared_ptr<TreasureBag> tb) {
        tbag = tb;
    }

    void release() {
        tbag.reset();
    }
};

And then construct your TreasureBag as a shared_ptr too:

std::shared_ptr<TreasureBag> tb = std::make_shared<TreasureBag>(5);
Sprite s1("s1");
s1.acquire(tb);

Upvotes: 1

Related Questions