Reputation: 2164
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
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
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