如何删除尚未指定给对象的指针 我是C++新手,现在正在做游戏。在游戏中,我会随着时间的推移随机生成敌人,我使用std::vector来实现这一点。我想我可以用像这样的东西 enemies.push_back(new Enemy(random_x, randomY));

如何删除尚未指定给对象的指针 我是C++新手,现在正在做游戏。在游戏中,我会随着时间的推移随机生成敌人,我使用std::vector来实现这一点。我想我可以用像这样的东西 enemies.push_back(new Enemy(random_x, randomY));,c++,pointers,vector,game-engine,C++,Pointers,Vector,Game Engine,在一个循环中,但现在我觉得这可能会导致内存泄漏,因为我没有删除指针。因此,我想了解如何防止内存泄漏;我是否应该找到一种方法来删除我创建的所有敌人,还是应该做一些完全不同的事情 只有在未首先释放备份存储而失去对对象的访问权限时,才会发生内存泄漏。这里的情况并非如此,因为您只需遍历敌人集合即可调用查找所有这些敌人 大概在某个时候你会从列表中删除敌人(例如,当你在游戏中杀死他们时)。此时,您应该删除它们,内存将被回收。只有在未首先释放备份存储的情况下失去对对象的访问时,才会发生内存泄漏。这里的情况并非

在一个循环中,但现在我觉得这可能会导致内存泄漏,因为我没有删除指针。因此,我想了解如何防止内存泄漏;我是否应该找到一种方法来删除我创建的所有敌人,还是应该做一些完全不同的事情

只有在未首先释放备份存储而失去对对象的访问权限时,才会发生内存泄漏。这里的情况并非如此,因为您只需遍历
敌人
集合即可调用查找所有这些敌人

大概在某个时候你会从列表中删除敌人(例如,当你在游戏中杀死他们时)。此时,您应该删除它们,内存将被回收。

只有在未首先释放备份存储的情况下失去对对象的访问时,才会发生内存泄漏。这里的情况并非如此,因为您只需遍历
敌人
集合即可调用查找所有这些敌人

大概在某个时候你会从列表中删除敌人(例如,当你在游戏中杀死他们时)。此时,您应该删除它们,内存将被回收。

只有在未首先释放备份存储的情况下失去对对象的访问时,才会发生内存泄漏。这里的情况并非如此,因为您只需遍历
敌人
集合即可调用查找所有这些敌人

大概在某个时候你会从列表中删除敌人(例如,当你在游戏中杀死他们时)。此时,您应该删除它们,内存将被回收。

只有在未首先释放备份存储的情况下失去对对象的访问时,才会发生内存泄漏。这里的情况并非如此,因为您只需遍历
敌人
集合即可调用查找所有这些敌人


大概在某个时候你会从列表中删除敌人(例如,当你在游戏中杀死他们时)。此时,您应该删除它们,内存将被回收。

有多种方法可以解决此问题

您可以使用原始指针,如
std::vector
中所述,然后在删除它们时需要删除它们:

delete *pos; // pos is an iterator pointing to the element to be deleted
enemies.erase(pos);

但是,这不是处理C++中的事情的方法。 如果您想在不访问列表的情况下传递“敌人”,可以使用

shared\u ptr
,如
std::vector
。然后你只需要擦除,一旦不再存在指向敌人的
shared\u ptr
,内存就会自动为你释放

enemies.erase(pos); // Nothing more needed, if someone still has a shared_ptr-copy 
                    // of the enemy it will stay in memory until that reference is gone
如果您总是使用列表访问敌人,您甚至可以使用
std::unique\u ptr
。但在这种情况下,最好使用最简单的形式:
std::vector
。这样,您就不必调用
new
。但这也使您无法使用多态性,而且根据您的
敌人
-类,副本可能非常昂贵

为什么多态性不起作用?
std::vector
通过复制将完整的
敌人
存储在其内存中。例如,如果敌人占用8个字节的内存,而向量中有5个敌人,理论上它将占用40个字节的内存(可能需要更多,但这是特定于实现的)

如果您试图存储一个派生的
extraemy
对象,该对象在位置3处添加了属性,需要额外4个字节,那么它将不起作用,因为向量中的每个条目都必须具有相同的大小

| Idx0  | Idx1  | Idx2  | Idx3  | Idx4 |
[Enemy1][Enemy2][ExtraToughEnemy3][Enemy4][Enemy5]
   8b      8b           12b          8b      8b
如果使用指针,可以避免这个问题,因为每个指针对象都具有相同的大小,但可以指向不同的派生对象

|  Idx0  |  Idx1  |  Idx2  |  Idx3  |  Idx4 |
[Enemy1*][Enemy2*][Enemy3*][Enemy4*][Enemy5*]
   4b       4b       4b       4b       4b
基类指针可以指向任何基类或派生对象。不过,您必须使用强制转换来访问
Enemy3*
的额外属性

关于共享指针和唯一指针的注意事项:

如果使用它们,可以考虑(根据编译器),甚至跳过使用<代码>新< /代码>,使用<代码> STD::MaMaMyAsdio<<代码>或<代码> STD::MaxIOxION/<代码>在堆上创建对象。 有多种方法可以解决这个问题

您可以使用原始指针,如
std::vector
中所述,然后在删除它们时需要删除它们:

delete *pos; // pos is an iterator pointing to the element to be deleted
enemies.erase(pos);

但是,这不是处理C++中的事情的方法。 如果您想在不访问列表的情况下传递“敌人”,可以使用

shared\u ptr
,如
std::vector
。然后你只需要擦除,一旦不再存在指向敌人的
shared\u ptr
,内存就会自动为你释放

enemies.erase(pos); // Nothing more needed, if someone still has a shared_ptr-copy 
                    // of the enemy it will stay in memory until that reference is gone
如果您总是使用列表访问敌人,您甚至可以使用
std::unique\u ptr
。但在这种情况下,最好使用最简单的形式:
std::vector
。这样,您就不必调用
new
。但这也使您无法使用多态性,而且根据您的
敌人
-类,副本可能非常昂贵

为什么多态性不起作用?
std::vector
通过复制将完整的
敌人
存储在其内存中。例如,如果敌人占用8个字节的内存,而向量中有5个敌人,理论上它将占用40个字节的内存(可能需要更多,但这是特定于实现的)

如果您试图存储一个派生的
extraemy
对象,该对象在位置3处添加了属性,需要额外4个字节,那么它将不起作用,因为向量中的每个条目都必须具有相同的大小

| Idx0  | Idx1  | Idx2  | Idx3  | Idx4 |
[Enemy1][Enemy2][ExtraToughEnemy3][Enemy4][Enemy5]
   8b      8b           12b          8b      8b
如果使用指针,可以避免这个问题,因为每个指针对象都具有相同的大小,但可以指向不同的派生对象

|  Idx0  |  Idx1  |  Idx2  |  Idx3  |  Idx4 |
[Enemy1*][Enemy2*][Enemy3*][Enemy4*][Enemy5*]
   4b       4b       4b       4b       4b
基类指针可以指向任何基类或派生对象。你会有