简体   繁体   中英

How would I store multiple instance objects correctly?

I am making an intermediate/advanced C++ program, a video game to be exact.

Lately I have been noticing that there is a good amount of memory being leaked, and I was wondering if maybe something is wrong with the way I am creating my instances.

Below is a summarized(but originally complex) class:

class theObject
{
 //Instance variables
 //Instance functions
};

With this object(along with any other objects that I am storing, I have an array index of every different variation template of theObject . That part is not important, but the way I am storing them(or in my opinion) is:

//NEWER VERSION WITH MORE INFO
void spawnTheObject()
{
 theObject* NewObj=ObjectArray[N];
 //I give the specific copy its individual parameters(such as its spawn location and few edited stats)
 NewObj->giveCustomStats(int,int,int,int);//hard-coded, not actual params
 NewObj->Spawn(float,float,float);
 myStorage.push_back(new theObject(*NewObj));
}


//OLDER VERSION
void spawnTheObject()
    {
     //create a copy of the arrayed object
     theObject* NewObj=new theObject(*ObjectArray[N]);
     //spawn the object(in this case it could be a monster), and I am spawning multiple copies of them obviously
     //then store into the storage object(currently a deque(originally a vector))
     myStorage.push_back(new theObject(*NewObj));
     //and delete the temporary one
     delete NewObj;
    }

I am currently using a deque(recently changed from using a vector) but I am seeing no difference in the memory usage. I have though found out from "comment tests" that these spawning functions I have are the reason for the memory leaks. Since this is the wrong way to create/spawn the instances, I was wondering if there is a better way to storing these objects.

tl;dr: What are some better objects to store a non-constant amount of objects and how?

I am guessing you never clear new spawn objects in myStorage that causes the memory to increase(as you refer to memory leak). If I am correct your myStorage is declared as below:

std::deque<theObject*> myStorage;

if you call either of below calls, the pointers to theObject are delete but the real dynamically allocated objects are not deleted.

 myStorage.pop_back();
 myStorage.clear();

Another small issue in your code, you are making unnecessary object allocate/dellocate in spawnTheObject() function.

How to clean container with pointer type

You need to iterate through each element in myStorage, delete the object then clear the container, for example:

for (std::deque<theObject*>::iterator iter=myStorage.begin();
     iter != myStorage.end(); ++iter)
{
   delete (*iter);
}
myStorage.clear();

Better solution:

Use smart pointers in std::deque or std::vector , then when you remove an element from STL container the object the pointer is pointing to is also deleted automatically.

 #include <memory>

 std::deque<std::shared_ptr<theObject> > myStorage;
 myStorage.push_back(std::shared_ptr<theObject>(new *ObjectArray[N]));

 mySorage.clear();  // all memories cleared properly, no worries

If you do not manually delete your objects from myStorage at the end of the game or when they need to be destroyed, there is your memory leak.

myStorage.push_back(new theObject(*NewObj));

The object being pushed into storage is allocated by you, so it should be destroyed by you when it needs to disappear.

Also I do not understand the need for the intermediate NewObj object, it isnt a memory leak but it is an unnecessary performance cost, 1 allocation/deallocation + 1 copy.

As Forever mentioned, your best bet is to start using smart pointers, either std::unique_ptr or std::shared_ptr (only if c++11).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM