如何正确存储多个实例对象

How would I store multiple instance objects correctly?

本文关键字:实例 对象 何正确 存储      更新时间:2023-10-16

我正在编写一个中级/高级c++程序,确切地说是一个电子游戏。

最近我一直注意到有大量的内存被泄露,我想知道是否我创建实例的方式有问题。

下面是一个总结的类(但最初很复杂):

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

使用这个对象(以及我存储的任何其他对象),我有theObject的每个不同变体模板的数组索引。这部分并不重要,但是我存储它们的方式(或者在我看来)是:

//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;
    }

我目前正在使用deque(最近从使用vector更改),但我看到内存使用没有差异。我从"注释测试"中发现,这些生成函数是导致内存泄漏的原因。因为这是错误的方式来创建/衍生的实例,我想知道是否有更好的方式来存储这些对象。

tl;dr:哪些对象更适合存储非恒定数量的对象?如何存储?

我猜你永远不会清除myStorage中导致内存增加的新刷出对象(当你提到内存泄漏时)。如果我是正确的,你的myStorage声明如下:

std::deque<theObject*> myStorage;

如果调用以下调用中的任何一个,指向object的指针将被删除,但实际动态分配的对象不会被删除。

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

你的代码中的另一个小问题,你在spawnTheObject()函数中做了不必要的对象分配/dellocate。

如何清理指针类型

您需要遍历myStorage中的每个元素,删除对象,然后清除容器,例如:

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

更好的解决方案:

std::dequestd::vector中使用智能指针,那么当您从STL容器中删除元素时,指针所指的对象也会自动删除。

 #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

如果你没有在游戏结束或需要销毁时手动删除myStorage中的对象,则存在内存泄漏。

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

被推入存储器的对象是由您分配的,因此当它需要消失时,应该由您销毁。

我也不明白需要中间的NewObj对象,它不是内存泄漏,但它是一个不必要的性能成本,1分配/释放+ 1拷贝。

正如Forever所提到的,您最好的选择是开始使用智能指针,std::unique_ptrstd::shared_ptr(仅适用于c++11)。