Утечка памяти после наведения на НОВЫЙ объект
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 ответа
Деструктор класса должен освобождать ресурсы, которые были получены в его конструкторе. Кажется, вы хотели отложить удаление массива, выделенного в одном классе, деструктору второго класса. Это никогда не хорошая идея. В лучшем случае вам не нужно ничего делать в деструкторе, потому что вы используете автоматическое хранение (означает, что подсказывает название: память управляется автоматически).
Ваш код может выглядеть так:
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;
(ничего нового!).
Как вы правильно предположили, утечки памяти вызваны неправильной очисткой всех 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;
}