指向NEW对象后的内存泄漏

时间:2018-12-07 18:51:45

标签: c++ pointers memory-leaks new-operator delete-operator

struct StructA {

    StructA(parameters) { ... } //StructA onstructor
};

struct StructB {

    StructA *pObjectA;
    int counter = 0;

    void function() {
        if (counter < 1) { pObjectA = new StructA[100]; }

        pObjectA[counter] = *new StructA(parameters); //Memory leak here
        counter++;
    }
};

struct StructC {

    StructB objectB;

    ~StructC() { //StructC destructor
        delete[] objectB.pObjectA;
        objectB.pObjectA = NULL;
    }
};

int main() {

    StructC objectC;
    for (int i = 0; i < 900; i++) {
        objectC.objectB.function();
    }

    return 0;
} //Struct C destructor here

我需要创建一个对象数组,然后每次调用objectB.function()时,都要将特定的参数传递给StructA的构造函数。上面的代码可以正常工作,除了内存泄漏,我无法摆脱。

我的猜测是StructC析构函数仅删除对象数组,而不删除每个* new StructA(parameters)。我尝试使用指针和delete []一点点,但是我得到的只是访问内存冲突错误。这是我能想到的唯一方法。感谢所有帮助。

2 个答案:

答案 0 :(得分:1)

类析构函数应该释放在其构造函数中获取的资源。似乎您想推迟删除在一个类中分配给第二个类的析构函数的数组。那绝不是一个好主意。最好的情况是,您无需在析构函数中执行任何操作,因为您使用的是自动存储(即名称所暗示的:内存是自动管理的)。

您的代码可能如下所示:

struct StructA {    
    StructA(parameters) { ... } //StructA onstructor
};

struct StructB {
    std::vector<StructA> pObjectA;
    int counter = 0;

    void function() {
        if (counter < 1) { pObjectA.reserve(100); }
        pObjectA.emplace_back(parameters);    
        counter++;
    }
};

struct StructC {
    StructB objectB;
};

int main() {

    StructC objectC;
    for (int i = 0; i < 900; i++) {
        objectC.objectB.function();
    }    
    return 0;
}

请注意,我试图保持结构不变,也许还有其他事情需要更改。例如,您不需要counter,因为您可以使用std::vector::size查询向量中的元素数。

PS:您已经注意到,这是内存泄漏:

  pObjectA[counter] = *new StructA(parameters); //Memory leak here

目前尚不清楚为什么首先要编写该代码。创建StructA类型的对象的惯用方式是StructA a;(不新鲜!)。

答案 1 :(得分:0)

正如您正确假设的那样,内存泄漏是由于未正确清理相应的new而清理所有delete引起的。但是,在惯用的C ++中,直接使用newdelete是没有用的。

使用std::vectorstd::shared_ptrstd::unique_ptr使RAII跟踪动态创建的对象,对它们的引用以及何时清除。它不仅更健壮,而且更短,更容易阅读。

使用代码的总体结构:

#include <memory>
#include <vector>

struct StructA {
};

struct StructB {
    std::vector<std::shared_ptr<StructA>> objectAs;

    void function() {
        objectAs.push_back(
            std::make_shared<StructA>( /*parameters*/ )
        );
    }
};

struct StructC {
    StructB objectB;
};

int main() {
    StructC objectC;
    for (int i = 0; i < 900; i++) {
        objectC.objectB.function();
    }
    return 0;
}