0

我正在制作一个中级/高级 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;
    }

我目前正在使用双端队列(最近从使用向量更改),但我没有看到内存使用量有任何差异。我虽然从“评论测试”中发现,我拥有的这些生成功能是内存泄漏的原因。由于这是创建/生成实例的错误方法,我想知道是否有更好的方法来存储这些对象。

tl; dr:有哪些更好的对象来存储非常量的对象以及如何存储?

4

2 回答 2

2

我猜你永远不会清除myStorage导致内存增加的新生成对象(正如你所说的内存泄漏)。如果我是正确的,您的 myStorage 声明如下:

std::deque<theObject*> myStorage;

如果您调用以下任一调用,则指向 theObject 的指针将被删除,但不会删除真正动态分配的对象。

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

您的代码中的另一个小问题是,您在函数中进行了不必要的对象分配/删除spawnTheObject()

如何使用指针类型清洁容器

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

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

更好的解决方案:

std::deque在or中使用智能指针std::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
于 2013-01-09T07:56:10.037 回答
0

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

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

被推入存储的对象是由你分配的,所以当它需要消失时应该由你销毁。

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

正如永远提到的,最好的选择是开始使用智能指针,std::unique_ptr或者std::shared_ptr(仅当 c++11 时)。

于 2013-01-09T06:38:35.427 回答