D
D
Denisca Gareev2021-06-12 09:47:22
C++ / C#
Denisca Gareev, 2021-06-12 09:47:22

How to delete an object declared in a function?

An example will make it clearer

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);
}

How to remove the output variable? Or how in principle it is possible to optimize the given code?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Bereznikov, 2021-06-12
@gdt

In general, two options can be assumed on the move, simple and correct.
An easy option - based on your when, you don't need to remove output. Make a new variable in main for the result, and remove it at the end of the main method:

const auto* test2 = testMatrix->mulVec(test);
delete test2;

The correct option is to never use raw pointers at all if possible. That is, something like this (the code has not been tested, something may need to be written a little differently, but the main idea is this):
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);
}

The smart pointer will take care of clearing the memory. Instead of shared_ptr, you can of course use other pointers, it may be correct to wrap the return value in std:: move.

W
Wataru, 2021-06-12
@wataru

It is possible to simply delete via delete after the call, but this is a terrible approach.
Actually, you don't need dynamic memory here. The Vector class itself does not consume much memory. Therefore, mulVec can return just a Vector, not a pointer to it. Matrix4x4 itself does not eat memory either, so there is no need to start pointers to it either. All the memory is inside it in the data pointer (by the way, do you delete this data in the ~Matrix4x4 destructor?).
If there is something else and the Vector is large, then return unique_ptr or shared_ptr to it. Then everything itself will be deleted when it is necessary.
And yet, in your current code, you highlight test in main, and then overwrite it. Here you have a memory leak. It had to be deleted before overwriting, it's a pointer. This is a good example of why it's bad to use raw pointers where you shouldn't. It's easy to make a mistake: you should always remember who is responsible for deleting the pointer.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question