提问者:小点点

保存指向本地区域中创建的堆的指针


我制作了一个“Planet”类,并且正在尝试在我的项目的客户机文件中基于这个类初始化一个向量数组。

void addPlanet(std::vector<Planet>& planets, std::string filePath)
{
    std::ifstream infile(filePath, std::ios_base::in);
 
    if (infile.fail()) {
        // File could not be opened
        return false;
    }
 
    std::string planetName, imagePath;
    float posX, posY, rotationZ, scaleX, scaleY;
    unsigned long long int planetMass;
 
    while (infile >> planetName >> posX >> posY >> rotationZ >> scaleX >> scaleY >> planetMass >> imagePath)
    {
        Planet* newPlanet = new Planet(sf::Vector2f(posX, posY), rotationZ, sf::Vector2f(scaleX, scaleY), planetMass, imagePath);
        
        planets.push_back(*newPlanet);
    }
 
    infile.close();
 
    return true;
}

但我不知道下面这段代码是否导致了内存泄漏:

while (infile >> planetName >> posX >> posY >> rotationZ >> scaleX >> scaleY >> planetMass >> imagePath)
{
    Planet* newPlanet = new Planet(sf::Vector2f(posX, posY), rotationZ, sf::Vector2f(scaleX, scaleY), planetMass, imagePath);
        
    planets.push_back(*newPlanet);
}

我是这样想的:

我为“Planet”类的新实例分配了动态内存。使用push_back方法-向量的内部迭代器成为指向新实例的第二个指针。并且当我们退出循环时,vector中仍然有一个指向新分配的堆的指针。

我是否正确地理解了所有内容,还是我只是不善于阅读文档?


共1个答案

匿名用户

您的代码将创建一个Planet对象:

Planet* newPlanet = new Planet(sf::Vector2f(posX, posY), rotationZ, sf::Vector2f(scaleX, scaleY), planetMass, imagePath);

然后,它将这个对象复制到向量中:

planets.push_back(*newPlanet);

但它不会释放对应于原始对象的内存。向量只拥有副本,而不拥有原始的行星对象。

您可以简单地解决此问题,但根本不使用new:

Planet newPlanet(sf::Vector2f(posX, posY), rotationZ, sf::Vector2f(scaleX, scaleY), planetMass, imagePath);
planets.push_back(std::move(newPlanet));

在这里,拥有newplanet对象的代码块就是代码块。

但是,您可能希望直接使用std::vector::emplace_back()而不是newpush_back():

planets.emplace_back(sf::Vector2f(posX, posY), rotationZ, sf::Vector2f(scaleX, scaleY), planetMass, imagePath);

通过这种方式,向量获取所创建的单个planet对象的所有权。