Утечка памяти после наведения на НОВЫЙ объект - PullRequest
0 голосов
/ 07 декабря 2018
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 удаляет только массив объектов, а не каждый * новый StructA (параметры).Я попытался немного поиграться с указателями и удалить [], но все, что я получил, это ошибки доступа к памяти.Это единственный способ думать, что это работает.Вся помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Деструктор класса должен освобождать ресурсы, которые были получены в его конструкторе.Кажется, вы хотели отложить удаление массива, выделенного в одном классе, деструктору второго класса.Это никогда не хорошая идея.В лучшем случае вам не нужно ничего делать в деструкторе, потому что вы используете автоматическое хранение (подразумевается то, что предполагает название: память управляется автоматически).

Ваш код может выглядеть следующим образом:

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; (не новый!).

0 голосов
/ 07 декабря 2018

Как вы правильно предположили, утечки памяти вызваны неправильной очисткой всех new с соответствующей delete.Однако в идиоматическом C ++ нет смысла использовать new и delete напрямую.

Используйте std::vector, std::shared_ptr и std::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;
}
...