如何删除尚未指定给对象的指针 我是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
基类指针可以指向任何基类或派生对象。你会有