@Denisca2828

Как удалить объект объявленный в функции?

На примере будет понятнее
class Vector{
public:
  float x = 0, y = 0, z = 0;
  Vector(float x, float y, float z);
}

class Matrix4x4{
public:
  float* data = new float[16];
  Vector* mulVec(Vector* inp){
    Vector* output = new Vector(...);
    /*...*/
    return output;
  }
}

int main(){
  Vector* test = new Vector(1, -1, 1);
  Matrix4x4 testMatrix = new Matrix4x4();
  test = testMatrix->mulVec(test);
}

Как удалить переменную output? Или же как впринципе можно оптимизировать данный код?
  • Вопрос задан
  • 59 просмотров
Пригласить эксперта
Ответы на вопрос 2
gdt
@gdt
Программист
В общем с ходу можно предположить два варианта, простой и правильный.
Простой вариант - исходя из вашего когда, вам не нужно удалять output. Заведите в main новую переменную для результата, и удаляйте её в конце метода main:
const auto* test2 = testMatrix->mulVec(test);
delete test2;


Правильный вариант заключается в том, чтобы по возможности вообще никогда не использовать сырые указатели. Т. е. примерно так (код не проверял, что-то может быть нужно чуть-чуть по-другому написать, но основная идея такая):
class Matrix4x4{
public:
  float* data = new float[16];
  std::shared_ptr<Vector> mulVec(std::shared_ptr<Vector> inp){
    const auto output = std::make_shared<Vector>(...);
    /*...*/
    return output;
  }
}

int main(){
  const auto test = std::make_shared<Vector>(1, -1, 1);
  const auto testMatrix = std::make_sharedMatrix4x4>();
  const auto mulResult = testMatrix->mulVec(test);
}


Умный указатель сам позаботится о том, чтобы очистить память. Вместо shared_ptr можно конечно и другие указатели использовать, возможно правильно будет значение return обернуть в std::move.
Ответ написан
Комментировать
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Можно просто удалять через delete после вызова, но это ужасный подход.

На самом деле, вам тут не нужна динамическая память. Сам класс Vector не жрет много памяти. Поэтому mulVec может возвращать просто Vector, а не указатель на него. Cам Matrix4x4 тоже не жрет память, поэтому не надо заводить и на него указатели. Вся память у него внутри в указателе data (кстати, вы же в деструкторе ~Matrix4x4 эту data удаляете же?).

Если же там еще что-то и Vector большой, то возвращайте unique_ptr или shared_ptr на него. Тогда все само удалится, когда надо.

И еще, в вашем текущем коде вы в main выделяете test, а потом перезаписываете. Тут у вас происходит утечка памяти. Его надо было delete-нуть перед перезаписью, это же указатель. Это хороший пример, почему вот так использовать сырые указатели где не надо - это плохо. Легко ошибиться: надо всегда помнить, кто ответственен за удалиение указателя.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы