I recently wrote a cpp file that I'm questioning. I'm unsure of whether the approach I took is correct or if it will cause damage to the heap.

The goal of the project is to be able to do "clean-up" on dynamically allocated memory by storing the created object in a static vector shared across the same classes.

The vector stores pointers, and unfortunately it doesn't seem as if clear or resize properly deletes or destructs the pointers stored in the vector so I'm manually doing it for each value in the vector. Is this the correct approach?

#include <iostream>
#include <vector>
class ManagedClass{
    private:
            static std::vector<ManagedClass*> track;
            short index;
            static short currentAmount;

    public:
            ManagedClass(){
                track.push_back(this);
                index = currentAmount++;
            }

            ~ManagedClass(){
                std::cout << "destructor called for-- " << index << std::endl;
                currentAmount--;
                if(currentAmount == 0){
                    std::cout << "Clearing the vector--" << std::endl;
                    std::vector<ManagedClass*> temp;
                    track = temp;
                    std::cout << "size of vector is now-- " << track.size() << std::endl;
                    currentAmount = 0;
                }
            }

            static void showAll() {
                std::vector<ManagedClass*>::iterator first = track.begin(), last = track.end();
                while(first != last){
                    std::cout << static_cast<ManagedClass*>(*first) << " " << std::flush;
                    first++;
                }
            }

            static void releaseAll(){
                    for(int i = track.size() + 1; i > 1; i--){
                        delete track[i - 2]; // is this safe?
                    }
            }
};

std::vector<ManagedClass*> temp;
std::vector<ManagedClass*> ManagedClass::track = temp;
short ManagedClass::currentAmount = 0;

int main(){
    new ManagedClass;
    new ManagedClass;
    new ManagedClass;

    ManagedClass::showAll();
    ManagedClass::releaseAll();

    std::cin.get();
    return 0;
}

Recommended Answers

All 6 Replies

erase() just removes an object from the vector, it does not delete the object. I would write that releaseAll() function like this:

static void releaseAll(){
   std::vector<ManagedClass*>::iterator first = track.begin()
   while( first != track.end() )
   {
         delete *first;
         first++;
   }
   track.erase(track.begin(),track.end());
}

erase() just removes an object from the vector, it does not delete the object. I would write that releaseAll() function like this:

static void releaseAll(){
   std::vector<ManagedClass*>::iterator first = track.begin()
   while( first != track.end() )
   {
         delete *first;
         first++;
   }
   track.erase(track.begin(),track.end());
}

I'm sorry... where did I use erase? O_O

I also wasn't aware of the erase function until now.

Earlier I was working with this program and I got a lot of errors from attempting to cast the object referenced by the iterator to a ManagedClass* then delete it. Afterwards I tried using resize and clear but got errors so I went the indice-reference approach.

Was it because I was calling a destructor/delete command by using resize/clear? Does erase simply make the reference variables in the vector point to NULL?

Sorry for the questions, it just seemed weird that the approach you're showing me now is similar to what I was working with earlier with the subtle difference of using erase instead of resize/clear.

>>nd unfortunately it doesn't seem as if clear or resize properly deletes or destructs the pointers

>>I'm sorry... where did I use erase? O_O
clear() is the same as erase(begin, end)

>>I got a lot of errors from attempting to cast the object referenced by the iterator to a ManagedClass
No casting necessary. I did not use a cast in the code I posted.

commented: Thanks a million =) +3

Thanks!

#include <iostream>
#include <vector>
class ManagedClass{
    private:
            static std::vector<ManagedClass*> track;
            short index;
            static short currentAmount;

    public:
            ManagedClass(){
                track.push_back(this);
                index = currentAmount++;
            }

            ~ManagedClass(){
                std::cout << "destructor called for-- " << index << std::endl;
                currentAmount--;
                if(currentAmount == 0){
                    std::cout << "size of vector is now-- " << track.size() << std::endl;
                }
            }

            static void showAll() {
                std::vector<ManagedClass*>::iterator first = track.begin(), last = track.end();
                while(first != last){
                    std::cout << *first << " " << std::flush; // fixed**
                    first++;
                }
            }

            static void releaseAll(){
               std::vector<ManagedClass*>::iterator first = track.begin();
               while( first != track.end() ){
                     delete *first;
                     first++;
               }
               track.erase(track.begin(),track.end());
            }
};

std::vector<ManagedClass*> temp;
std::vector<ManagedClass*> ManagedClass::track = temp;
short ManagedClass::currentAmount = 0;

int main(){
    new ManagedClass;
    new ManagedClass;
    new ManagedClass;

    ManagedClass::showAll();
    ManagedClass::releaseAll();

    std::cin.get();
    return 0;
}

you don't need the case on line 26: std::cout << *first << " " << std::flush; Your class doesn't have an overloaded << operator so I don't see how the above will compile.

you don't need the case on line 26: std::cout << *first << " " << std::flush; Your class doesn't have an overloaded << operator so I don't see how the above will compile.

If I recall, the iterator simply returns what is located at the theoretical position of the vector.

Since the vector is holding pointers, then the *first is simply returning the pointer, in which the address of the location of the object will be printed.

At least that's what I'd think... I haven't had any issues during compile/run-time.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.