C++ 指针向量中的内存泄漏

C++ 指针向量中的内存泄漏,c++,pointers,vector,memory-leaks,C++,Pointers,Vector,Memory Leaks,我正在制作一个使用大量包含指针的向量的程序,我担心删除指针的方式可能会导致内存泄漏 下面是我如何将项目符号添加到向量的示例: Bullet* aNewBullet; aNewBullet = new Bullet(x,y,dirX,dirY,size,duration); aNewBullet->assignTexture(btext); bulletVector.push_back(aNewBullet); 下面是我如何从向量中删除项目符号(例如,如果它超出其范围) inti=0; 而

我正在制作一个使用大量包含指针的向量的程序,我担心删除指针的方式可能会导致内存泄漏

下面是我如何将项目符号添加到向量的示例:

Bullet* aNewBullet;
aNewBullet = new Bullet(x,y,dirX,dirY,size,duration);
aNewBullet->assignTexture(btext);
bulletVector.push_back(aNewBullet);
下面是我如何从向量中删除项目符号(例如,如果它超出其范围)

inti=0;
而(igetDuration()==0)
bulletVector.erase(bulletVector.begin()+i);
否则i++;
}
我是不是告诉向量去删除子弹? 或者我该怎么做

int i=0;
while (i<bulletVector.size()){
    if (bulletVector[i]->getDuration() ==0)
        delete bulletVector[i];
        bulletVector.erase(bulletVector.begin() + i);
    else i++;
}
inti=0;
而(igetDuration()==0)
删除[i];
bulletVector.erase(bulletVector.begin()+i);
否则i++;
}
相反?这会不会先删除指针,然后再从向量中删除记录,从而弄乱向量大小


删除指针是否也会调用项目符号析构函数(~bullet())?

当然,您必须通过delete自己删除项目符号。但您的删除周期不正确

要使用某些条件从vector中删除值,请使用以下命令:

auto condFunc = [](const Bullet* x)
{
    bool rez = (x->getDuration() == 0);
    if(rez)
        delete x;
    return rez;
};
bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());
bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
bulletVector.back().assignTexture(btext);
bulletVector.erase(std::remove_if(
                    bulletVector.begin(), 
                    bulletVector.end(),
                    [](auto const& b) { return b.getDuration() == 0; }),
                   bulletVector.end());

当然,您必须通过delete自己删除项目符号。但您的删除周期不正确

要使用某些条件从vector中删除值,请使用以下命令:

auto condFunc = [](const Bullet* x)
{
    bool rez = (x->getDuration() == 0);
    if(rez)
        delete x;
    return rez;
};
bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());
bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
bulletVector.back().assignTexture(btext);
bulletVector.erase(std::remove_if(
                    bulletVector.begin(), 
                    bulletVector.end(),
                    [](auto const& b) { return b.getDuration() == 0; }),
                   bulletVector.end());

在第一个代码示例中,您没有删除任何
Bullet
对象。擦除
vector
只会删除指针,而不会删除指向的对象

您的第二个示例确实正确地删除了
Bullet
s(并不是在给定条件和循环设置的情况下全部删除),但前提是您在修改向量的所有点执行了必要的删除,并手动确保指针不会被删除两次(例如,因为它存在于两个向量中)。这不是容器的使用方式

如果您确实想存储指针并让向量拥有它们,那么您应该使用
std::vector
,当向量被擦除时,它将正确地删除
项目符号
对象。但是,矢量将变为不可复制(仅可移动)

但是,如果向量应该拥有
项目符号
s,那么您可以直接将它们存储在向量中:
std::vector


如果向量不应该拥有
项目符号
s,那么删除它们的责任在于实际拥有它们的任何对象,但即使如此,也需要做出一些努力来确保删除的指针不会保留在向量中。

在第一个代码示例中,您没有删除任何
项目符号
对象。擦除
vector
只会删除指针,而不会删除指向的对象

您的第二个示例确实正确地删除了
Bullet
s(并不是在给定条件和循环设置的情况下全部删除),但前提是您在修改向量的所有点执行了必要的删除,并手动确保指针不会被删除两次(例如,因为它存在于两个向量中)。这不是容器的使用方式

如果您确实想存储指针并让向量拥有它们,那么您应该使用
std::vector
,当向量被擦除时,它将正确地删除
项目符号
对象。但是,矢量将变为不可复制(仅可移动)

但是,如果向量应该拥有
项目符号
s,那么您可以直接将它们存储在向量中:
std::vector


如果向量不应该拥有
项目符号
s,那么删除它们的责任在于实际拥有它们的任何对象,但即使如此,也需要做出一些努力,以确保删除的指针不会保留在向量中。

您需要
删除
使用
新建
创建的对象(除非您将指针交给<代码> STD::UNIQUYGPTR 或<代码> STD::SysDypPTR )。考虑让向量成为对象的所有者。< /P>
std::vector<Bullet> bulletVector;

// in C++17, emplace_back returns a ref to the new Bullet:
Bullet& aNewBullet = bulletVector.emplace_back(x,y,dirX,dirY,size,duration);

// pre C++17:
bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
Bullet& aNewBullet = bulletVector.back();

aNewBullet.assignTexture(btext);
std::vector bulletVector;
//在C++17中,emplace_back返回对新项目符号的引用:
Bullet&aNewBullet=bulletVector.向后放置(x,y,dirX,dirY,大小,持续时间);
//C++17之前的版本:
炮弹向量。后置(x,y,dirX,dirY,大小,持续时间);
Bullet&aNewBullet=bulletVector.back();
aNewBullet.纹理(btext);

当您现在
erase()
从向量中删除一个对象时,它将被自动销毁。

您需要
删除
新建
创建的对象(除非您将指针交给
std::unique\ptr
std::shared\ptr
)考虑让向量成为对象的所有者。< /P>
std::vector<Bullet> bulletVector;

// in C++17, emplace_back returns a ref to the new Bullet:
Bullet& aNewBullet = bulletVector.emplace_back(x,y,dirX,dirY,size,duration);

// pre C++17:
bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
Bullet& aNewBullet = bulletVector.back();

aNewBullet.assignTexture(btext);
std::vector bulletVector;
//在C++17中,emplace_back返回对新项目符号的引用:
Bullet&aNewBullet=bulletVector.向后放置(x,y,dirX,dirY,大小,持续时间);
//C++17之前的版本:
炮弹向量。后置(x,y,dirX,dirY,大小,持续时间);
Bullet&aNewBullet=bulletVector.back();
aNewBullet.纹理(btext);
当您现在
erase()
从向量中删除一个对象时,它将被自动销毁。

首先,您很有可能通过不首先使用手动动态分配来解决问题。您可以使用动态分配(例如,多态存储)是有原因的,但即使这样,您也应该转向智能指针,而不是手动分配

扔掉指针

要使用具体对象(而不是指针)的正则向量执行此操作,只需

std::vector<Bullet> bulletVector;
根据达到零的持续时间删除所有元素只需使用以下习惯用法:

auto condFunc = [](const Bullet* x)
{
    bool rez = (x->getDuration() == 0);
    if(rez)
        delete x;
    return rez;
};
bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());
bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
bulletVector.back().assignTexture(btext);
bulletVector.erase(std::remove_if(
                    bulletVector.begin(), 
                    bulletVector.end(),
                    [](auto const& b) { return b.getDuration() == 0; }),
                   bulletVector.end());
请记住,虽然这很容易成为存储这些内容的首选方法,但它需要对代码的其余部分进行更改。无论您当前在何处执行此操作:

bulletVector[i]->doSomething();
将成为

bulletVector[i].doSomething();

更智能的指针

如果您必须使用动态分配,请不要使用手动管理的指针。它们会导致内存泄漏和所有权丢失